diff --git a/.circleci/config.yml b/.circleci/config.yml index f8623698..7499579a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,14 +2,16 @@ version: 2 jobs: go-version-latest: docker: - - image: cimg/go:1.18-node + - image: cimg/go:1.19-node + resource_class: large steps: - checkout - run: make - run: make alltest go-version-last: docker: - - image: cimg/go:1.17-node + - image: cimg/go:1.18-node + resource_class: large steps: - checkout - run: make diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000..c9051f38 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,41 @@ +name: golangci-lint +on: + push: + branches: + - master + - dev + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.49.0 + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the all caching functionality will be complete disabled, + # takes precedence over all other caching options. + # skip-cache: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index 40914a46..25bd7615 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.19 - run: | # https://github.com/actions/setup-go/issues/107 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..aefd4688 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,141 @@ +service: + # When updating this, also update the version stored in docker/build-tools/Dockerfile in the istio/tools repo. + golangci-lint-version: 1.49.x # use the fixed version to not introduce new linters unexpectedly + +run: + concurrency: 4 + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 20m + build-tags: + - integ + - integfuzz + # which dirs to skip: they won't be analyzed; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but next dirs are always skipped independently + # from this option's value: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs: + - genfiles$ + - vendor$ + - bin$ + + # which files to skip: they will be analyzed, but issues from them + # won't be reported. Default value is empty list, but there is + # no need to include all autogenerated files, we confidently recognize + # autogenerated files. If it's not please let us know. + skip-files: + - ".*\\.pb\\.go" + - ".*\\.gen\\.go" + +linters: + disable-all: true + enable: + - unused + - errcheck + - exportloopref + - gocritic + - gofumpt + - goimports + - revive + - gosimple + - govet + - ineffassign + - lll + - misspell + - staticcheck + - stylecheck + - typecheck + - unconvert + - unparam + - gci + - bodyclose + - gosec + - asciicheck + - prealloc + - predeclared + - makezero + fast: false + +linters-settings: + errcheck: + # report about not checking of errors in type assetions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: false + govet: + # report about shadowed variables + check-shadowing: false + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + ignore-words: + - cancelled + - marshalled + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 160 + # tab width in spaces. Default to 1. + tab-width: 1 + gocritic: + disabled-checks: + - exitAfterDefer + unused: + check-exported: false + unparam: + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + gci: + sections: + - standard + - default + - prefix(github.com/fatedier/frp/) + gosec: + severity: "low" + confidence: "low" + excludes: + - G102 + - G112 + - G306 + - G401 + - G402 + - G404 + - G501 + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + # exclude: + # - composite literal uses unkeyed fields + + exclude-rules: + # Exclude some linters from running on test files. + - path: _test\.go$|^tests/|^samples/ + linters: + - errcheck + - maligned + + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: true + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 diff --git a/client/admin.go b/client/admin.go index 6a6ceecb..f96e1bc1 100644 --- a/client/admin.go +++ b/client/admin.go @@ -20,10 +20,10 @@ import ( "net/http/pprof" "time" + "github.com/gorilla/mux" + "github.com/fatedier/frp/assets" frpNet "github.com/fatedier/frp/pkg/util/net" - - "github.com/gorilla/mux" ) var ( @@ -77,6 +77,8 @@ func (svr *Service) RunAdminServer(address string) (err error) { return err } - go server.Serve(ln) + go func() { + _ = server.Serve(ln) + }() return } diff --git a/client/admin_api.go b/client/admin_api.go index e434fcb1..545ba7fc 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -49,7 +49,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { log.Info("api response [/api/reload], code [%d]", res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -68,7 +68,6 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { return } log.Info("success reload conf") - return } type StatusResp struct { @@ -173,7 +172,7 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { defer func() { log.Info("Http response [/api/status]") buf, _ = json.Marshal(&res) - w.Write(buf) + _, _ = w.Write(buf) }() ps := svr.ctl.pm.GetAllProxyStatus() @@ -202,7 +201,6 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { sort.Sort(ByProxyStatusResp(res.STCP)) sort.Sort(ByProxyStatusResp(res.XTCP)) sort.Sort(ByProxyStatusResp(res.SUDP)) - return } // GET api/config @@ -214,7 +212,7 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) { log.Info("Http get response [/api/config], code [%d]", res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -254,7 +252,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { log.Info("Http put response [/api/config], code [%d]", res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -315,7 +313,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { } content = strings.Join(newRows, "\n") - err = os.WriteFile(svr.cfgFile, []byte(content), 0644) + err = os.WriteFile(svr.cfgFile, []byte(content), 0o644) if err != nil { res.Code = 500 res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err) diff --git a/client/control.go b/client/control.go index ef9a766f..db8c019a 100644 --- a/client/control.go +++ b/client/control.go @@ -21,9 +21,13 @@ import ( "net" "runtime/debug" "strconv" - "sync" "time" + "github.com/fatedier/golib/control/shutdown" + "github.com/fatedier/golib/crypto" + libdial "github.com/fatedier/golib/net/dial" + fmux "github.com/hashicorp/yamux" + "github.com/fatedier/frp/client/proxy" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" @@ -31,11 +35,6 @@ import ( "github.com/fatedier/frp/pkg/transport" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/control/shutdown" - "github.com/fatedier/golib/crypto" - libdial "github.com/fatedier/golib/net/dial" - fmux "github.com/hashicorp/yamux" ) type Control struct { @@ -79,8 +78,6 @@ type Control struct { // The UDP port that the server is listening on serverUDPPort int - mu sync.RWMutex - xl *xlog.Logger // service context @@ -95,8 +92,8 @@ func NewControl(ctx context.Context, runID string, conn net.Conn, session *fmux. pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, serverUDPPort int, - authSetter auth.Setter) *Control { - + authSetter auth.Setter, +) *Control { // new xlog instance ctl := &Control{ runID: runID, @@ -131,7 +128,6 @@ func (ctl *Control) Run() { // start all visitors go ctl.vm.Run() - return } func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { @@ -400,24 +396,21 @@ func (ctl *Control) worker() { go ctl.reader() go ctl.writer() - select { - case <-ctl.closedCh: - // close related channels and wait until other goroutines done - close(ctl.readCh) - ctl.readerShutdown.WaitDone() - ctl.msgHandlerShutdown.WaitDone() + <-ctl.closedCh + // close related channels and wait until other goroutines done + close(ctl.readCh) + ctl.readerShutdown.WaitDone() + ctl.msgHandlerShutdown.WaitDone() - close(ctl.sendCh) - ctl.writerShutdown.WaitDone() + close(ctl.sendCh) + ctl.writerShutdown.WaitDone() - ctl.pm.Close() - ctl.vm.Close() + ctl.pm.Close() + ctl.vm.Close() - close(ctl.closedDoneCh) - if ctl.session != nil { - ctl.session.Close() - } - return + close(ctl.closedDoneCh) + if ctl.session != nil { + ctl.session.Close() } } diff --git a/client/event/event.go b/client/event/event.go index eedeff51..bf7090d9 100644 --- a/client/event/event.go +++ b/client/event/event.go @@ -6,9 +6,7 @@ import ( "github.com/fatedier/frp/pkg/msg" ) -var ( - ErrPayloadType = errors.New("error payload type") -) +var ErrPayloadType = errors.New("error payload type") type Handler func(payload interface{}) error diff --git a/client/health/health.go b/client/health/health.go index 829bee3d..0ee3d04a 100644 --- a/client/health/health.go +++ b/client/health/health.go @@ -26,9 +26,7 @@ import ( "github.com/fatedier/frp/pkg/util/xlog" ) -var ( - ErrHealthCheckType = errors.New("error health check type") -) +var ErrHealthCheckType = errors.New("error health check type") type Monitor struct { checkType string @@ -54,8 +52,8 @@ type Monitor struct { func NewMonitor(ctx context.Context, checkType string, intervalS int, timeoutS int, maxFailedTimes int, addr string, url string, - statusNormalFn func(), statusFailedFn func()) *Monitor { - + statusNormalFn func(), statusFailedFn func(), +) *Monitor { if intervalS <= 0 { intervalS = 10 } @@ -152,7 +150,7 @@ func (monitor *Monitor) doTCPCheck(ctx context.Context) error { } func (monitor *Monitor) doHTTPCheck(ctx context.Context) error { - req, err := http.NewRequest("GET", monitor.url, nil) + req, err := http.NewRequestWithContext(ctx, "GET", monitor.url, nil) if err != nil { return err } @@ -161,7 +159,7 @@ func (monitor *Monitor) doHTTPCheck(ctx context.Context) error { return err } defer resp.Body.Close() - io.Copy(io.Discard, resp.Body) + _, _ = io.Copy(io.Discard, resp.Body) if resp.StatusCode/100 != 2 { return fmt.Errorf("do http health check, StatusCode is [%d] not 2xx", resp.StatusCode) diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index 340da950..158773bc 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -24,14 +24,6 @@ import ( "sync" "time" - "github.com/fatedier/frp/pkg/config" - "github.com/fatedier/frp/pkg/msg" - plugin "github.com/fatedier/frp/pkg/plugin/client" - "github.com/fatedier/frp/pkg/proto/udp" - "github.com/fatedier/frp/pkg/util/limit" - frpNet "github.com/fatedier/frp/pkg/util/net" - "github.com/fatedier/frp/pkg/util/xlog" - "github.com/fatedier/golib/errors" frpIo "github.com/fatedier/golib/io" libdial "github.com/fatedier/golib/net/dial" @@ -39,6 +31,14 @@ import ( fmux "github.com/hashicorp/yamux" pp "github.com/pires/go-proxyproto" "golang.org/x/time/rate" + + "github.com/fatedier/frp/pkg/config" + "github.com/fatedier/frp/pkg/msg" + plugin "github.com/fatedier/frp/pkg/plugin/client" + "github.com/fatedier/frp/pkg/proto/udp" + "github.com/fatedier/frp/pkg/util/limit" + frpNet "github.com/fatedier/frp/pkg/util/net" + "github.com/fatedier/frp/pkg/util/xlog" ) // Proxy defines how to handle work connections for different proxy type. @@ -322,7 +322,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { // Wait for client address at most 5 seconds. var natHoleRespMsg msg.NatHoleResp - clientConn.SetReadDeadline(time.Now().Add(5 * time.Second)) + _ = clientConn.SetReadDeadline(time.Now().Add(5 * time.Second)) buf := pool.GetBuf(1024) n, err := clientConn.Read(buf) @@ -335,8 +335,8 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { xl.Error("get natHoleRespMsg error: %v", err) return } - clientConn.SetReadDeadline(time.Time{}) - clientConn.Close() + _ = clientConn.SetReadDeadline(time.Time{}) + _ = clientConn.Close() if natHoleRespMsg.Error != "" { xl.Error("natHoleRespMsg get error info: %s", natHoleRespMsg.Error) @@ -357,10 +357,13 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { xl.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr) return } - pxy.sendDetectMsg(host, int(port), laddr, []byte(natHoleRespMsg.Sid)) + _ = pxy.sendDetectMsg(host, int(port), laddr, []byte(natHoleRespMsg.Sid)) xl.Trace("send all detect msg done") - msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{}) + if err := msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{}); err != nil { + xl.Error("write message error: %v", err) + return + } // Listen for clientConn's address and wait for visitor connection lConn, err := net.ListenUDP("udp", laddr) @@ -370,7 +373,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { } defer lConn.Close() - lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) + _ = lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) sidBuf := pool.GetBuf(1024) var uAddr *net.UDPAddr n, uAddr, err = lConn.ReadFromUDP(sidBuf) @@ -378,7 +381,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { xl.Warn("get sid from visitor error: %v", err) return } - lConn.SetReadDeadline(time.Time{}) + _ = lConn.SetReadDeadline(time.Time{}) if string(sidBuf[:n]) != natHoleRespMsg.Sid { xl.Warn("incorrect sid from visitor") return @@ -386,7 +389,10 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { pool.PutBuf(sidBuf) xl.Info("nat hole connection make success, sid [%s]", natHoleRespMsg.Sid) - lConn.WriteToUDP(sidBuf[:n], uAddr) + if _, err := lConn.WriteToUDP(sidBuf[:n], uAddr); err != nil { + xl.Error("write uaddr error: %v", err) + return + } kcpConn, err := frpNet.NewKCPConnFromUDP(lConn, false, uAddr.String()) if err != nil { @@ -424,12 +430,13 @@ func (pxy *XTCPProxy) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, c return err } - //uConn := ipv4.NewConn(tConn) - //uConn.SetTTL(3) + // uConn := ipv4.NewConn(tConn) + // uConn.SetTTL(3) - tConn.Write(content) - tConn.Close() - return nil + if _, err := tConn.Write(content); err != nil { + return err + } + return tConn.Close() } // UDP @@ -539,7 +546,7 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { } } } - heartbeatFn := func(conn net.Conn, sendCh chan msg.Message) { + heartbeatFn := func(sendCh chan msg.Message) { var errRet error for { time.Sleep(time.Duration(30) * time.Second) @@ -554,7 +561,7 @@ func (pxy *UDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { go workConnSenderFn(pxy.workConn, pxy.sendCh) go workConnReaderFn(pxy.workConn, pxy.readCh) - go heartbeatFn(pxy.workConn, pxy.sendCh) + go heartbeatFn(pxy.sendCh) udp.Forwarder(pxy.localAddr, pxy.readCh, pxy.sendCh, int(pxy.clientCfg.UDPPacketSize)) } @@ -685,7 +692,7 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { } } - heartbeatFn := func(conn net.Conn, sendCh chan msg.Message) { + heartbeatFn := func(sendCh chan msg.Message) { ticker := time.NewTicker(30 * time.Second) defer func() { ticker.Stop() @@ -711,14 +718,15 @@ func (pxy *SUDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { go workConnSenderFn(workConn, sendCh) go workConnReaderFn(workConn, readCh) - go heartbeatFn(workConn, sendCh) + go heartbeatFn(sendCh) udp.Forwarder(pxy.localAddr, readCh, sendCh, int(pxy.clientCfg.UDPPacketSize)) } // Common handler for tcp work connections. func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf, proxyPlugin plugin.Plugin, - baseInfo *config.BaseProxyConf, limiter *rate.Limiter, workConn net.Conn, encKey []byte, m *msg.StartWorkConn) { + baseInfo *config.BaseProxyConf, limiter *rate.Limiter, workConn net.Conn, encKey []byte, m *msg.StartWorkConn, +) { xl := xlog.FromContextSafe(ctx) var ( remote io.ReadWriteCloser @@ -773,7 +781,7 @@ func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf } buf := bytes.NewBuffer(nil) - h.WriteTo(buf) + _, _ = h.WriteTo(buf) extraInfo = buf.Bytes() } } @@ -800,7 +808,11 @@ func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf localConn.RemoteAddr().String(), workConn.LocalAddr().String(), workConn.RemoteAddr().String()) if len(extraInfo) > 0 { - localConn.Write(extraInfo) + if _, err := localConn.Write(extraInfo); err != nil { + workConn.Close() + xl.Error("write extraInfo to local conn error: %v", err) + return + } } frpIo.Join(localConn, remote) diff --git a/client/proxy/proxy_manager.go b/client/proxy/proxy_manager.go index 51a8e28e..563531e8 100644 --- a/client/proxy/proxy_manager.go +++ b/client/proxy/proxy_manager.go @@ -6,12 +6,12 @@ import ( "net" "sync" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/client/event" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" ) type Manager struct { @@ -113,10 +113,8 @@ func (pm *Manager) Reload(pxyCfgs map[string]config.ProxyConf) { cfg, ok := pxyCfgs[name] if !ok { del = true - } else { - if !pxy.Cfg.Compare(cfg) { - del = true - } + } else if !pxy.Cfg.Compare(cfg) { + del = true } if del { diff --git a/client/proxy/proxy_wrapper.go b/client/proxy/proxy_wrapper.go index 035926e3..af217f06 100644 --- a/client/proxy/proxy_wrapper.go +++ b/client/proxy/proxy_wrapper.go @@ -8,13 +8,13 @@ import ( "sync/atomic" "time" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/client/event" "github.com/fatedier/frp/client/health" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" ) const ( @@ -27,9 +27,9 @@ const ( ) var ( - statusCheckInterval time.Duration = 3 * time.Second - waitResponseTimeout = 20 * time.Second - startErrTimeout = 30 * time.Second + statusCheckInterval = 3 * time.Second + waitResponseTimeout = 20 * time.Second + startErrTimeout = 30 * time.Second ) type WorkingStatus struct { @@ -145,7 +145,7 @@ func (pw *Wrapper) Stop() { } func (pw *Wrapper) close() { - pw.handler(&event.CloseProxyPayload{ + _ = pw.handler(&event.CloseProxyPayload{ CloseProxyMsg: &msg.CloseProxy{ ProxyName: pw.Name, }, @@ -174,7 +174,7 @@ func (pw *Wrapper) checkWorker() { var newProxyMsg msg.NewProxy pw.Cfg.MarshalToMsg(&newProxyMsg) pw.lastSendStartMsg = now - pw.handler(&event.StartProxyPayload{ + _ = pw.handler(&event.StartProxyPayload{ NewProxyMsg: &newProxyMsg, }) } @@ -201,7 +201,7 @@ func (pw *Wrapper) checkWorker() { func (pw *Wrapper) statusNormalCallback() { xl := pw.xl atomic.StoreUint32(&pw.health, 0) - errors.PanicToError(func() { + _ = errors.PanicToError(func() { select { case pw.healthNotifyCh <- struct{}{}: default: @@ -213,7 +213,7 @@ func (pw *Wrapper) statusNormalCallback() { func (pw *Wrapper) statusFailedCallback() { xl := pw.xl atomic.StoreUint32(&pw.health, 1) - errors.PanicToError(func() { + _ = errors.PanicToError(func() { select { case pw.healthNotifyCh <- struct{}{}: default: diff --git a/client/service.go b/client/service.go index 3a08d4e1..37558767 100644 --- a/client/service.go +++ b/client/service.go @@ -28,6 +28,10 @@ import ( "sync/atomic" "time" + "github.com/fatedier/golib/crypto" + libdial "github.com/fatedier/golib/net/dial" + fmux "github.com/hashicorp/yamux" + "github.com/fatedier/frp/assets" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" @@ -38,10 +42,6 @@ import ( "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/xlog" - "github.com/fatedier/golib/crypto" - libdial "github.com/fatedier/golib/net/dial" - - fmux "github.com/hashicorp/yamux" ) func init() { @@ -81,8 +81,12 @@ type Service struct { cancel context.CancelFunc } -func NewService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, cfgFile string) (svr *Service, err error) { - +func NewService( + cfg config.ClientCommonConf, + pxyCfgs map[string]config.ProxyConf, + visitorCfgs map[string]config.VisitorConf, + cfgFile string, +) (svr *Service, err error) { ctx, cancel := context.WithCancel(context.Background()) svr = &Service{ authSetter: auth.NewAuthSetter(cfg.ClientConfig), @@ -208,7 +212,7 @@ func (svr *Service) keepControllerWorking() { xl.Warn("reconnect to server error: %v, wait %v for another retry", err, delayTime) util.RandomSleep(delayTime, 0.9, 1.1) - delayTime = delayTime * 2 + delayTime *= 2 if delayTime > maxDelayTime { delayTime = maxDelayTime } @@ -333,11 +337,11 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) { } var loginRespMsg msg.LoginResp - conn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = conn.SetReadDeadline(time.Now().Add(10 * time.Second)) if err = msg.ReadMsgInto(conn, &loginRespMsg); err != nil { return } - conn.SetReadDeadline(time.Time{}) + _ = conn.SetReadDeadline(time.Time{}) if loginRespMsg.Error != "" { err = fmt.Errorf("%s", loginRespMsg.Error) diff --git a/client/visitor.go b/client/visitor.go index ba1cd7cb..1d7386f7 100644 --- a/client/visitor.go +++ b/client/visitor.go @@ -24,17 +24,17 @@ import ( "sync" "time" + "github.com/fatedier/golib/errors" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/golib/pool" + fmux "github.com/hashicorp/yamux" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/proto/udp" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" - frpIo "github.com/fatedier/golib/io" - "github.com/fatedier/golib/pool" - fmux "github.com/hashicorp/yamux" ) // Visitor is used for forward traffics from local port tot remote service. @@ -71,9 +71,8 @@ func NewVisitor(ctx context.Context, ctl *Control, cfg config.VisitorConf) (visi } type BaseVisitor struct { - ctl *Control - l net.Listener - closed bool + ctl *Control + l net.Listener mu sync.RWMutex ctx context.Context @@ -138,13 +137,13 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) { } var newVisitorConnRespMsg msg.NewVisitorConnResp - visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg) if err != nil { xl.Warn("get newVisitorConnRespMsg error: %v", err) return } - visitorConn.SetReadDeadline(time.Time{}) + _ = visitorConn.SetReadDeadline(time.Time{}) if newVisitorConnRespMsg.Error != "" { xl.Warn("start new visitor connection error: %s", newVisitorConnRespMsg.Error) @@ -239,7 +238,7 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) { // Wait for client address at most 10 seconds. var natHoleRespMsg msg.NatHoleResp - visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) buf := pool.GetBuf(1024) n, err := visitorConn.Read(buf) if err != nil { @@ -252,7 +251,7 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) { xl.Warn("get natHoleRespMsg error: %v", err) return } - visitorConn.SetReadDeadline(time.Time{}) + _ = visitorConn.SetReadDeadline(time.Time{}) pool.PutBuf(buf) if natHoleRespMsg.Error != "" { @@ -279,17 +278,20 @@ func (sv *XTCPVisitor) handleConn(userConn net.Conn) { } defer lConn.Close() - lConn.Write([]byte(natHoleRespMsg.Sid)) + if _, err := lConn.Write([]byte(natHoleRespMsg.Sid)); err != nil { + xl.Error("write sid error: %v", err) + return + } // read ack sid from client sidBuf := pool.GetBuf(1024) - lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) + _ = lConn.SetReadDeadline(time.Now().Add(8 * time.Second)) n, err = lConn.Read(sidBuf) if err != nil { xl.Warn("get sid from client error: %v", err) return } - lConn.SetReadDeadline(time.Time{}) + _ = lConn.SetReadDeadline(time.Time{}) if string(sidBuf[:n]) != natHoleRespMsg.Sid { xl.Warn("incorrect sid from client") return @@ -411,7 +413,6 @@ func (sv *SUDPVisitor) dispatcher() { default: } } - } func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) { @@ -437,13 +438,13 @@ func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) { ) // frpc will send heartbeat in workConn to frpc visitor for keeping alive - conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + _ = conn.SetReadDeadline(time.Now().Add(60 * time.Second)) if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil { xl.Warn("read from workconn for user udp conn error: %v", errRet) return } - conn.SetReadDeadline(time.Time{}) + _ = conn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { case *msg.Ping: xl.Debug("frpc visitor get ping message from frpc") @@ -523,12 +524,12 @@ func (sv *SUDPVisitor) getNewVisitorConn() (net.Conn, error) { } var newVisitorConnRespMsg msg.NewVisitorConnResp - visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second)) err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg) if err != nil { return nil, fmt.Errorf("frpc read newVisitorConnRespMsg error: %v", err) } - visitorConn.SetReadDeadline(time.Time{}) + _ = visitorConn.SetReadDeadline(time.Time{}) if newVisitorConnRespMsg.Error != "" { return nil, fmt.Errorf("start new visitor connection error: %s", newVisitorConnRespMsg.Error) diff --git a/client/visitor_manager.go b/client/visitor_manager.go index 642b21e8..8df47150 100644 --- a/client/visitor_manager.go +++ b/client/visitor_manager.go @@ -65,7 +65,7 @@ func (vm *VisitorManager) Run() { name := cfg.GetBaseInfo().ProxyName if _, exist := vm.visitors[name]; !exist { xl.Info("try to start visitor [%s]", name) - vm.startVisitor(cfg) + _ = vm.startVisitor(cfg) } } vm.mu.Unlock() @@ -99,10 +99,8 @@ func (vm *VisitorManager) Reload(cfgs map[string]config.VisitorConf) { cfg, ok := cfgs[name] if !ok { del = true - } else { - if !oldCfg.Compare(cfg) { - del = true - } + } else if !oldCfg.Compare(cfg) { + del = true } if del { @@ -123,13 +121,12 @@ func (vm *VisitorManager) Reload(cfgs map[string]config.VisitorConf) { if _, ok := vm.cfgs[name]; !ok { vm.cfgs[name] = cfg addNames = append(addNames, name) - vm.startVisitor(cfg) + _ = vm.startVisitor(cfg) } } if len(addNames) > 0 { xl.Info("visitor added: %v", addNames) } - return } func (vm *VisitorManager) Close() { diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 2e19fce4..4e193b7e 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -19,10 +19,10 @@ import ( "os" "strings" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/reload.go b/cmd/frpc/sub/reload.go index c625daed..258317e7 100644 --- a/cmd/frpc/sub/reload.go +++ b/cmd/frpc/sub/reload.go @@ -22,9 +22,9 @@ import ( "os" "strings" - "github.com/fatedier/frp/pkg/config" - "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go index f8d7eb17..cea8ecc6 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -26,13 +26,13 @@ import ( "syscall" "time" + "github.com/spf13/cobra" + "github.com/fatedier/frp/client" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/version" - - "github.com/spf13/cobra" ) const ( @@ -107,7 +107,7 @@ var rootCmd = &cobra.Command{ // Note that it's only designed for testing. It's not guaranteed to be stable. if cfgDir != "" { var wg sync.WaitGroup - filepath.WalkDir(cfgDir, func(path string, d fs.DirEntry, err error) error { + _ = filepath.WalkDir(cfgDir, func(path string, d fs.DirEntry, err error) error { if err != nil { return nil } @@ -183,7 +183,7 @@ func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) { cfg.Complete() if err = cfg.Validate(); err != nil { - err = fmt.Errorf("Parse config error: %v", err) + err = fmt.Errorf("parse config error: %v", err) return } return @@ -203,7 +203,6 @@ func startService( visitorCfgs map[string]config.VisitorConf, cfgFile string, ) (err error) { - log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel, cfg.LogMaxDays, cfg.DisableLogColor) diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go index 52c1c195..c9a6a98d 100644 --- a/cmd/frpc/sub/status.go +++ b/cmd/frpc/sub/status.go @@ -23,11 +23,11 @@ import ( "os" "strings" - "github.com/fatedier/frp/client" - "github.com/fatedier/frp/pkg/config" - "github.com/rodaine/table" "github.com/spf13/cobra" + + "github.com/fatedier/frp/client" + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/cmd/frpc/sub/stcp.go b/cmd/frpc/sub/stcp.go index 45f01e59..989387bb 100644 --- a/cmd/frpc/sub/stcp.go +++ b/cmd/frpc/sub/stcp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/sudp.go b/cmd/frpc/sub/sudp.go index 45c5ad61..c781223d 100644 --- a/cmd/frpc/sub/sudp.go +++ b/cmd/frpc/sub/sudp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/udp.go b/cmd/frpc/sub/udp.go index 2ce4327e..984ad068 100644 --- a/cmd/frpc/sub/udp.go +++ b/cmd/frpc/sub/udp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frpc/sub/verify.go b/cmd/frpc/sub/verify.go index 76872b90..c86b1e82 100644 --- a/cmd/frpc/sub/verify.go +++ b/cmd/frpc/sub/verify.go @@ -18,9 +18,9 @@ import ( "fmt" "os" - "github.com/fatedier/frp/pkg/config" - "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/cmd/frpc/sub/xtcp.go b/cmd/frpc/sub/xtcp.go index 6c6c7d84..069cce7e 100644 --- a/cmd/frpc/sub/xtcp.go +++ b/cmd/frpc/sub/xtcp.go @@ -18,10 +18,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" - - "github.com/spf13/cobra" ) func init() { diff --git a/cmd/frps/root.go b/cmd/frps/root.go index d31944ac..955c90fb 100644 --- a/cmd/frps/root.go +++ b/cmd/frps/root.go @@ -18,14 +18,14 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/server" - - "github.com/spf13/cobra" ) const ( @@ -50,16 +50,13 @@ var ( dashboardUser string dashboardPwd string enablePrometheus bool - assetsDir string logFile string logLevel string logMaxDays int64 disableLogColor bool token string subDomainHost string - tcpMux bool allowPorts string - maxPoolCount int64 maxPortsPerClient int64 tlsOnly bool dashboardTLSMode bool @@ -151,7 +148,7 @@ func parseServerCommonCfg(fileType int, source []byte) (cfg config.ServerCommonC cfg.Complete() err = cfg.Validate() if err != nil { - err = fmt.Errorf("Parse config error: %v", err) + err = fmt.Errorf("parse config error: %v", err) return } return @@ -189,7 +186,7 @@ func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) { // e.g. 1000-2000,2001,2002,3000-4000 ports, errRet := util.ParseRangeNumbers(allowPorts) if errRet != nil { - err = fmt.Errorf("Parse conf error: allow_ports: %v", errRet) + err = fmt.Errorf("parse conf error: allow_ports: %v", errRet) return } diff --git a/cmd/frps/verify.go b/cmd/frps/verify.go index 35b2acdf..42f2ca74 100644 --- a/cmd/frps/verify.go +++ b/cmd/frps/verify.go @@ -18,9 +18,9 @@ import ( "fmt" "os" - "github.com/fatedier/frp/pkg/config" - "github.com/spf13/cobra" + + "github.com/fatedier/frp/pkg/config" ) func init() { diff --git a/dockerfiles/Dockerfile-for-frpc b/dockerfiles/Dockerfile-for-frpc index ece950f2..b749be07 100644 --- a/dockerfiles/Dockerfile-for-frpc +++ b/dockerfiles/Dockerfile-for-frpc @@ -1,4 +1,4 @@ -FROM golang:1.18 AS building +FROM golang:1.19 AS building COPY . /building WORKDIR /building diff --git a/dockerfiles/Dockerfile-for-frps b/dockerfiles/Dockerfile-for-frps index d8ab8247..cd716123 100644 --- a/dockerfiles/Dockerfile-for-frps +++ b/dockerfiles/Dockerfile-for-frps @@ -1,4 +1,4 @@ -FROM golang:1.18 AS building +FROM golang:1.19 AS building COPY . /building WORKDIR /building diff --git a/go.mod b/go.mod index 0a92dfb5..02f2b1f2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/fatedier/frp -go 1.16 +go 1.18 require ( github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 @@ -13,21 +13,54 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c - github.com/leodido/go-urn v1.2.1 // indirect github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.13.0 github.com/pires/go-proxyproto v0.6.2 - github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect github.com/prometheus/client_golang v1.11.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 github.com/stretchr/testify v1.7.0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d - golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba gopkg.in/ini.v1 v1.62.0 - gopkg.in/square/go-jose.v2 v2.4.1 // indirect k8s.io/apimachinery v0.21.2 k8s.io/client-go v0.21.2 ) + +require ( + github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/go-playground/locales v0.13.0 // indirect + github.com/go-playground/universal-translator v0.17.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/klauspost/cpuid/v2 v2.0.6 // indirect + github.com/klauspost/reedsolomon v1.9.15 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.26.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect + github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect + golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect + golang.org/x/text v0.3.6 // indirect + google.golang.org/appengine v1.6.5 // indirect + google.golang.org/protobuf v1.26.0 // indirect + gopkg.in/square/go-jose.v2 v2.4.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/go.sum b/go.sum index 433f03e2..7a0d8515 100644 --- a/go.sum +++ b/go.sum @@ -55,7 +55,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -383,7 +382,6 @@ github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVc github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E= -github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/hack/run-e2e.sh b/hack/run-e2e.sh index ee396652..d8cfb052 100755 --- a/hack/run-e2e.sh +++ b/hack/run-e2e.sh @@ -5,7 +5,7 @@ ROOT=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/.. && pwd) which ginkgo &> /dev/null if [ $? -ne 0 ]; then echo "ginkgo not found, try to install..." - go install github.com/onsi/ginkgo/ginkgo@latest + go install github.com/onsi/ginkgo/ginkgo@v1.16.5 fi debug=false diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index 8a9f3404..831180f4 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -18,10 +18,10 @@ import ( "context" "fmt" - "github.com/fatedier/frp/pkg/msg" - "github.com/coreos/go-oidc" "golang.org/x/oauth2/clientcredentials" + + "github.com/fatedier/frp/pkg/msg" ) type OidcClientConfig struct { @@ -34,7 +34,7 @@ type OidcClientConfig struct { // is "". OidcClientSecret string `ini:"oidc_client_secret" json:"oidc_client_secret"` // OidcAudience specifies the audience of the token in OIDC authentication - //if AuthenticationMethod == "oidc". By default, this value is "". + // if AuthenticationMethod == "oidc". By default, this value is "". OidcAudience string `ini:"oidc_audience" json:"oidc_audience"` // OidcTokenEndpointURL specifies the URL which implements OIDC Token Endpoint. // It will be used to get an OIDC token if AuthenticationMethod == "oidc". diff --git a/pkg/config/client.go b/pkg/config/client.go index f503711b..eaf8adb0 100644 --- a/pkg/config/client.go +++ b/pkg/config/client.go @@ -20,10 +20,10 @@ import ( "path/filepath" "strings" + "gopkg.in/ini.v1" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/util/util" - - "gopkg.in/ini.v1" ) // ClientCommonConf contains information for a client service. It is @@ -113,7 +113,7 @@ type ClientCommonConf struct { // all supplied proxies are enabled. By default, this value is an empty // set. Start []string `ini:"start" json:"start"` - //Start map[string]struct{} `json:"start"` + // Start map[string]struct{} `json:"start"` // Protocol specifies the protocol to use when interacting with the server. // Valid values are "tcp", "kcp" and "websocket". By default, this value // is "tcp". @@ -214,7 +214,7 @@ func (cfg *ClientCommonConf) Validate() error { } } - if cfg.TLSEnable == false { + if !cfg.TLSEnable { if cfg.TLSCertFile != "" { fmt.Println("WARNING! tls_cert_file is invalid when tls_enable is false") } @@ -281,7 +281,6 @@ func LoadAllProxyConfsFromIni( source interface{}, start []string, ) (map[string]ProxyConf, map[string]VisitorConf, error) { - f, err := ini.LoadSources(ini.LoadOptions{ Insensitive: false, InsensitiveSections: false, @@ -366,7 +365,6 @@ func LoadAllProxyConfsFromIni( } func renderRangeProxyTemplates(f *ini.File, section *ini.Section) error { - // Validation localPortStr := section.Key("local_port").String() remotePortStr := section.Key("remote_port").String() @@ -404,8 +402,12 @@ func renderRangeProxyTemplates(f *ini.File, section *ini.Section) error { } copySection(section, tmpsection) - tmpsection.NewKey("local_port", fmt.Sprintf("%d", localPorts[i])) - tmpsection.NewKey("remote_port", fmt.Sprintf("%d", remotePorts[i])) + if _, err := tmpsection.NewKey("local_port", fmt.Sprintf("%d", localPorts[i])); err != nil { + return fmt.Errorf("local_port new key in section error: %v", err) + } + if _, err := tmpsection.NewKey("remote_port", fmt.Sprintf("%d", remotePorts[i])); err != nil { + return fmt.Errorf("remote_port new key in section error: %v", err) + } } return nil @@ -413,6 +415,6 @@ func renderRangeProxyTemplates(f *ini.File, section *ini.Section) error { func copySection(source, target *ini.Section) { for key, value := range source.KeysHash() { - target.NewKey(key, value) + _, _ = target.NewKey(key, value) } } diff --git a/pkg/config/client_test.go b/pkg/config/client_test.go index 12f1c9e1..ccff2293 100644 --- a/pkg/config/client_test.go +++ b/pkg/config/client_test.go @@ -17,18 +17,17 @@ package config import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/consts" - - "github.com/stretchr/testify/assert" ) const ( testUser = "test" ) -var ( - testClientBytesWithFull = []byte(` +var testClientBytesWithFull = []byte(` # [common] is integral section [common] server_addr = 0.0.0.9 @@ -237,7 +236,6 @@ var ( use_encryption = false use_compression = false `) -) func Test_LoadClientCommonConf(t *testing.T) { assert := assert.New(t) diff --git a/pkg/config/parse.go b/pkg/config/parse.go index 7767981e..9f4cdb6b 100644 --- a/pkg/config/parse.go +++ b/pkg/config/parse.go @@ -42,7 +42,7 @@ func ParseClientConfig(filePath string) ( } cfg.Complete() if err = cfg.Validate(); err != nil { - err = fmt.Errorf("Parse config error: %v", err) + err = fmt.Errorf("parse config error: %v", err) return } diff --git a/pkg/config/proxy.go b/pkg/config/proxy.go index e168520d..92b499f2 100644 --- a/pkg/config/proxy.go +++ b/pkg/config/proxy.go @@ -21,10 +21,10 @@ import ( "strconv" "strings" + "gopkg.in/ini.v1" + "github.com/fatedier/frp/pkg/consts" "github.com/fatedier/frp/pkg/msg" - - "gopkg.in/ini.v1" ) // Proxy @@ -420,10 +420,6 @@ func (cfg *BaseProxyConf) checkForCli() (err error) { return nil } -func (cfg *BaseProxyConf) checkForSvr(conf ServerCommonConf) error { - return nil -} - // DomainConf func (cfg *DomainConf) check() (err error) { if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" { diff --git a/pkg/config/proxy_test.go b/pkg/config/proxy_test.go index 68c87b95..c603dd7f 100644 --- a/pkg/config/proxy_test.go +++ b/pkg/config/proxy_test.go @@ -17,10 +17,10 @@ package config import ( "testing" - "github.com/fatedier/frp/pkg/consts" "github.com/stretchr/testify/assert" - "gopkg.in/ini.v1" + + "github.com/fatedier/frp/pkg/consts" ) var ( @@ -49,7 +49,6 @@ func Test_Proxy_UnmarshalFromIni(t *testing.T) { source []byte expected ProxyConf }{ - { sname: "ssh", source: []byte(` @@ -457,5 +456,4 @@ func Test_RangeProxy_UnmarshalFromIni(t *testing.T) { assert.Equal(c.expected, actual) } - } diff --git a/pkg/config/server.go b/pkg/config/server.go index 50eb3054..62644558 100644 --- a/pkg/config/server.go +++ b/pkg/config/server.go @@ -18,12 +18,12 @@ import ( "fmt" "strings" + "github.com/go-playground/validator/v10" + "gopkg.in/ini.v1" + "github.com/fatedier/frp/pkg/auth" plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/pkg/util/util" - - "github.com/go-playground/validator/v10" - "gopkg.in/ini.v1" ) // ServerCommonConf contains information for a server service. It is @@ -236,7 +236,6 @@ func GetDefaultServerConf() ServerCommonConf { } func UnmarshalServerConfFromIni(source interface{}) (ServerCommonConf, error) { - f, err := ini.LoadSources(ini.LoadOptions{ Insensitive: false, InsensitiveSections: false, @@ -308,7 +307,7 @@ func (cfg *ServerCommonConf) Complete() { } func (cfg *ServerCommonConf) Validate() error { - if cfg.DashboardTLSMode == false { + if !cfg.DashboardTLSMode { if cfg.DashboardTLSCertFile != "" { fmt.Println("WARNING! dashboard_tls_cert_file is invalid when dashboard_tls_mode is false") } diff --git a/pkg/config/server_test.go b/pkg/config/server_test.go index 8646ca62..5dee66db 100644 --- a/pkg/config/server_test.go +++ b/pkg/config/server_test.go @@ -17,10 +17,10 @@ package config import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/fatedier/frp/pkg/auth" plugin "github.com/fatedier/frp/pkg/plugin/server" - - "github.com/stretchr/testify/assert" ) func Test_LoadServerCommonConf(t *testing.T) { @@ -126,10 +126,10 @@ func Test_LoadServerCommonConf(t *testing.T) { HeartbeatTimeout: 99, UserConnTimeout: 9, AllowPorts: map[int]struct{}{ - 10: struct{}{}, - 11: struct{}{}, - 12: struct{}{}, - 99: struct{}{}, + 10: {}, + 11: {}, + 12: {}, + 99: {}, }, MaxPoolCount: 59, MaxPortsPerClient: 9, diff --git a/pkg/config/types.go b/pkg/config/types.go index 062cc746..28a0e46d 100644 --- a/pkg/config/types.go +++ b/pkg/config/types.go @@ -75,21 +75,22 @@ func (q *BandwidthQuantity) UnmarshalString(s string) error { f float64 err error ) - if strings.HasSuffix(s, "MB") { + switch { + case strings.HasSuffix(s, "MB"): base = MB fstr := strings.TrimSuffix(s, "MB") f, err = strconv.ParseFloat(fstr, 64) if err != nil { return err } - } else if strings.HasSuffix(s, "KB") { + case strings.HasSuffix(s, "KB"): base = KB fstr := strings.TrimSuffix(s, "KB") f, err = strconv.ParseFloat(fstr, 64) if err != nil { return err } - } else { + default: return errors.New("unit not support") } diff --git a/pkg/config/value.go b/pkg/config/value.go index e44fbd69..2f228823 100644 --- a/pkg/config/value.go +++ b/pkg/config/value.go @@ -21,9 +21,7 @@ import ( "text/template" ) -var ( - glbEnvs map[string]string -) +var glbEnvs map[string]string func init() { glbEnvs = make(map[string]string) diff --git a/pkg/config/visitor.go b/pkg/config/visitor.go index aede14d8..3d9440cd 100644 --- a/pkg/config/visitor.go +++ b/pkg/config/visitor.go @@ -18,9 +18,9 @@ import ( "fmt" "reflect" - "github.com/fatedier/frp/pkg/consts" - "gopkg.in/ini.v1" + + "github.com/fatedier/frp/pkg/consts" ) // Visitor @@ -136,6 +136,7 @@ func (cfg *BaseVisitorConf) check() (err error) { } func (cfg *BaseVisitorConf) unmarshalFromIni(prefix string, name string, section *ini.Section) error { + _ = section // Custom decoration after basic unmarshal: // proxy name diff --git a/pkg/config/visitor_test.go b/pkg/config/visitor_test.go index ce200ed0..cdfbbf46 100644 --- a/pkg/config/visitor_test.go +++ b/pkg/config/visitor_test.go @@ -17,10 +17,10 @@ package config import ( "testing" - "github.com/fatedier/frp/pkg/consts" - "github.com/stretchr/testify/assert" "gopkg.in/ini.v1" + + "github.com/fatedier/frp/pkg/consts" ) const testVisitorPrefix = "test." diff --git a/pkg/consts/consts.go b/pkg/consts/consts.go index 907bc73e..9e443834 100644 --- a/pkg/consts/consts.go +++ b/pkg/consts/consts.go @@ -16,26 +16,26 @@ package consts var ( // proxy status - Idle string = "idle" - Working string = "working" - Closed string = "closed" - Online string = "online" - Offline string = "offline" + Idle = "idle" + Working = "working" + Closed = "closed" + Online = "online" + Offline = "offline" // proxy type - TCPProxy string = "tcp" - UDPProxy string = "udp" - TCPMuxProxy string = "tcpmux" - HTTPProxy string = "http" - HTTPSProxy string = "https" - STCPProxy string = "stcp" - XTCPProxy string = "xtcp" - SUDPProxy string = "sudp" + TCPProxy = "tcp" + UDPProxy = "udp" + TCPMuxProxy = "tcpmux" + HTTPProxy = "http" + HTTPSProxy = "https" + STCPProxy = "stcp" + XTCPProxy = "xtcp" + SUDPProxy = "sudp" // authentication method - TokenAuthMethod string = "token" - OidcAuthMethod string = "oidc" + TokenAuthMethod = "token" + OidcAuthMethod = "oidc" // TCP multiplexer - HTTPConnectTCPMultiplexer string = "httpconnect" + HTTPConnectTCPMultiplexer = "httpconnect" ) diff --git a/pkg/metrics/aggregate/server.go b/pkg/metrics/aggregate/server.go index 1ff15e42..354d85c2 100644 --- a/pkg/metrics/aggregate/server.go +++ b/pkg/metrics/aggregate/server.go @@ -30,7 +30,7 @@ func EnablePrometheus() { sm.Add(prometheus.ServerMetrics) } -var sm *serverMetrics = &serverMetrics{} +var sm = &serverMetrics{} func init() { metrics.Register(sm) diff --git a/pkg/metrics/mem/server.go b/pkg/metrics/mem/server.go index 55d8daf1..38a8c68b 100644 --- a/pkg/metrics/mem/server.go +++ b/pkg/metrics/mem/server.go @@ -23,9 +23,12 @@ import ( server "github.com/fatedier/frp/server/metrics" ) -var sm *serverMetrics = newServerMetrics() -var ServerMetrics server.ServerMetrics -var StatsCollector Collector +var ( + sm = newServerMetrics() + + ServerMetrics server.ServerMetrics + StatsCollector Collector +) func init() { ServerMetrics = sm diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 6520317d..696496a2 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -4,5 +4,7 @@ import ( "github.com/fatedier/frp/pkg/metrics/aggregate" ) -var EnableMem = aggregate.EnableMem -var EnablePrometheus = aggregate.EnablePrometheus +var ( + EnableMem = aggregate.EnableMem + EnablePrometheus = aggregate.EnablePrometheus +) diff --git a/pkg/metrics/prometheus/server.go b/pkg/metrics/prometheus/server.go index 9cfdfda6..19eceb72 100644 --- a/pkg/metrics/prometheus/server.go +++ b/pkg/metrics/prometheus/server.go @@ -1,9 +1,9 @@ package prometheus import ( - "github.com/fatedier/frp/server/metrics" - "github.com/prometheus/client_golang/prometheus" + + "github.com/fatedier/frp/server/metrics" ) const ( diff --git a/pkg/msg/ctl.go b/pkg/msg/ctl.go index 0eafdbcc..bf0c71a7 100644 --- a/pkg/msg/ctl.go +++ b/pkg/msg/ctl.go @@ -22,9 +22,7 @@ import ( type Message = jsonMsg.Message -var ( - msgCtl *jsonMsg.MsgCtl -) +var msgCtl *jsonMsg.MsgCtl func init() { msgCtl = jsonMsg.NewMsgCtl() diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go index ba6dd63e..4b2823c7 100644 --- a/pkg/msg/msg.go +++ b/pkg/msg/msg.go @@ -37,28 +37,26 @@ const ( TypeNatHoleSid = '5' ) -var ( - msgTypeMap = map[byte]interface{}{ - TypeLogin: Login{}, - TypeLoginResp: LoginResp{}, - TypeNewProxy: NewProxy{}, - TypeNewProxyResp: NewProxyResp{}, - TypeCloseProxy: CloseProxy{}, - TypeNewWorkConn: NewWorkConn{}, - TypeReqWorkConn: ReqWorkConn{}, - TypeStartWorkConn: StartWorkConn{}, - TypeNewVisitorConn: NewVisitorConn{}, - TypeNewVisitorConnResp: NewVisitorConnResp{}, - TypePing: Ping{}, - TypePong: Pong{}, - TypeUDPPacket: UDPPacket{}, - TypeNatHoleVisitor: NatHoleVisitor{}, - TypeNatHoleClient: NatHoleClient{}, - TypeNatHoleResp: NatHoleResp{}, - TypeNatHoleClientDetectOK: NatHoleClientDetectOK{}, - TypeNatHoleSid: NatHoleSid{}, - } -) +var msgTypeMap = map[byte]interface{}{ + TypeLogin: Login{}, + TypeLoginResp: LoginResp{}, + TypeNewProxy: NewProxy{}, + TypeNewProxyResp: NewProxyResp{}, + TypeCloseProxy: CloseProxy{}, + TypeNewWorkConn: NewWorkConn{}, + TypeReqWorkConn: ReqWorkConn{}, + TypeStartWorkConn: StartWorkConn{}, + TypeNewVisitorConn: NewVisitorConn{}, + TypeNewVisitorConnResp: NewVisitorConnResp{}, + TypePing: Ping{}, + TypePong: Pong{}, + TypeUDPPacket: UDPPacket{}, + TypeNatHoleVisitor: NatHoleVisitor{}, + TypeNatHoleClient: NatHoleClient{}, + TypeNatHoleResp: NatHoleResp{}, + TypeNatHoleClientDetectOK: NatHoleClientDetectOK{}, + TypeNatHoleSid: NatHoleSid{}, +} // When frpc start, client send this message to login to server. type Login struct { @@ -129,8 +127,7 @@ type NewWorkConn struct { Timestamp int64 `json:"timestamp,omitempty"` } -type ReqWorkConn struct { -} +type ReqWorkConn struct{} type StartWorkConn struct { ProxyName string `json:"proxy_name,omitempty"` @@ -187,8 +184,7 @@ type NatHoleResp struct { Error string `json:"error,omitempty"` } -type NatHoleClientDetectOK struct { -} +type NatHoleClientDetectOK struct{} type NatHoleSid struct { Sid string `json:"sid,omitempty"` diff --git a/pkg/nathole/nathole.go b/pkg/nathole/nathole.go index 545ad7aa..da8b49c4 100644 --- a/pkg/nathole/nathole.go +++ b/pkg/nathole/nathole.go @@ -7,15 +7,15 @@ import ( "sync" "time" + "github.com/fatedier/golib/errors" + "github.com/fatedier/golib/pool" + "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/util" - - "github.com/fatedier/golib/errors" - "github.com/fatedier/golib/pool" ) -// Timeout seconds. +// NatHoleTimeout seconds. var NatHoleTimeout int64 = 10 type SidRequest struct { @@ -107,7 +107,7 @@ func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) { session := &Session{ Sid: sid, VisitorAddr: raddr, - NotifyCh: make(chan struct{}, 0), + NotifyCh: make(chan struct{}), } nc.mu.Lock() clientCfg, ok := nc.clientCfgs[m.ProxyName] @@ -115,14 +115,14 @@ func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) { nc.mu.Unlock() errInfo := fmt.Sprintf("xtcp server for [%s] doesn't exist", m.ProxyName) log.Debug(errInfo) - nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) + _, _ = nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) return } if m.SignKey != util.GetAuthKey(clientCfg.Sk, m.Timestamp) { nc.mu.Unlock() errInfo := fmt.Sprintf("xtcp connection of [%s] auth failed", m.ProxyName) log.Debug(errInfo) - nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) + _, _ = nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr) return } @@ -151,7 +151,7 @@ func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) { case <-session.NotifyCh: resp := nc.GenNatHoleResponse(session, "") log.Trace("send nat hole response to visitor") - nc.listener.WriteToUDP(resp, raddr) + _, _ = nc.listener.WriteToUDP(resp, raddr) case <-time.After(time.Duration(NatHoleTimeout) * time.Second): return } @@ -169,7 +169,7 @@ func (nc *Controller) HandleClient(m *msg.NatHoleClient, raddr *net.UDPAddr) { resp := nc.GenNatHoleResponse(session, "") log.Trace("send nat hole response to client") - nc.listener.WriteToUDP(resp, raddr) + _, _ = nc.listener.WriteToUDP(resp, raddr) } func (nc *Controller) GenNatHoleResponse(session *Session, errInfo string) []byte { diff --git a/pkg/plugin/client/http2https.go b/pkg/plugin/client/http2https.go index 3074cddf..f50a6c41 100644 --- a/pkg/plugin/client/http2https.go +++ b/pkg/plugin/client/http2https.go @@ -86,17 +86,20 @@ func NewHTTP2HTTPSPlugin(params map[string]string) (Plugin, error) { } p.s = &http.Server{ - Handler: rp, + Handler: rp, + ReadHeaderTimeout: 0, } - go p.s.Serve(listener) + go func() { + _ = p.s.Serve(listener) + }() return p, nil } func (p *HTTP2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - p.l.PutConn(wrapConn) + _ = p.l.PutConn(wrapConn) } func (p *HTTP2HTTPSPlugin) Name() string { diff --git a/pkg/plugin/client/http_proxy.go b/pkg/plugin/client/http_proxy.go index 45bd3a9a..78930e39 100644 --- a/pkg/plugin/client/http_proxy.go +++ b/pkg/plugin/client/http_proxy.go @@ -22,10 +22,10 @@ import ( "net/http" "strings" - frpNet "github.com/fatedier/frp/pkg/util/net" - frpIo "github.com/fatedier/golib/io" gnet "github.com/fatedier/golib/net" + + frpNet "github.com/fatedier/frp/pkg/util/net" ) const PluginHTTPProxy = "http_proxy" @@ -56,7 +56,9 @@ func NewHTTPProxyPlugin(params map[string]string) (Plugin, error) { Handler: hp, } - go hp.s.Serve(listener) + go func() { + _ = hp.s.Serve(listener) + }() return hp, nil } @@ -86,8 +88,7 @@ func (hp *HTTPProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBuf return } - hp.l.PutConn(sc) - return + _ = hp.l.PutConn(sc) } func (hp *HTTPProxy) Close() error { @@ -153,7 +154,7 @@ func (hp *HTTPProxy) ConnectHandler(rw http.ResponseWriter, req *http.Request) { client.Close() return } - client.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) + _, _ = client.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) go frpIo.Join(remote, client) } @@ -188,7 +189,10 @@ func (hp *HTTPProxy) handleConnectReq(req *http.Request, rwc io.ReadWriteCloser) defer rwc.Close() if ok := hp.Auth(req); !ok { res := getBadResponse() - res.Write(rwc) + _ = res.Write(rwc) + if res.Body != nil { + res.Body.Close() + } return } @@ -200,10 +204,10 @@ func (hp *HTTPProxy) handleConnectReq(req *http.Request, rwc io.ReadWriteCloser) ProtoMajor: 1, ProtoMinor: 1, } - res.Write(rwc) + _ = res.Write(rwc) return } - rwc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) + _, _ = rwc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n")) frpIo.Join(remote, rwc) } diff --git a/pkg/plugin/client/https2http.go b/pkg/plugin/client/https2http.go index 5aec067b..18138dc1 100644 --- a/pkg/plugin/client/https2http.go +++ b/pkg/plugin/client/https2http.go @@ -106,7 +106,9 @@ func NewHTTPS2HTTPPlugin(params map[string]string) (Plugin, error) { } ln := tls.NewListener(listener, tlsConfig) - go p.s.Serve(ln) + go func() { + _ = p.s.Serve(ln) + }() return p, nil } @@ -122,7 +124,7 @@ func (p *HTTPS2HTTPPlugin) genTLSConfig() (*tls.Config, error) { func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - p.l.PutConn(wrapConn) + _ = p.l.PutConn(wrapConn) } func (p *HTTPS2HTTPPlugin) Name() string { diff --git a/pkg/plugin/client/https2https.go b/pkg/plugin/client/https2https.go index cefa2030..596bdc13 100644 --- a/pkg/plugin/client/https2https.go +++ b/pkg/plugin/client/https2https.go @@ -111,7 +111,9 @@ func NewHTTPS2HTTPSPlugin(params map[string]string) (Plugin, error) { } ln := tls.NewListener(listener, tlsConfig) - go p.s.Serve(ln) + go func() { + _ = p.s.Serve(ln) + }() return p, nil } @@ -127,7 +129,7 @@ func (p *HTTPS2HTTPSPlugin) genTLSConfig() (*tls.Config, error) { func (p *HTTPS2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - p.l.PutConn(wrapConn) + _ = p.l.PutConn(wrapConn) } func (p *HTTPS2HTTPSPlugin) Name() string { diff --git a/pkg/plugin/client/socks5.go b/pkg/plugin/client/socks5.go index 3a543d9d..f731e87d 100644 --- a/pkg/plugin/client/socks5.go +++ b/pkg/plugin/client/socks5.go @@ -19,9 +19,9 @@ import ( "log" "net" - frpNet "github.com/fatedier/frp/pkg/util/net" - gosocks5 "github.com/armon/go-socks5" + + frpNet "github.com/fatedier/frp/pkg/util/net" ) const PluginSocks5 = "socks5" @@ -32,9 +32,6 @@ func init() { type Socks5Plugin struct { Server *gosocks5.Server - - user string - passwd string } func NewSocks5Plugin(params map[string]string) (p Plugin, err error) { @@ -56,7 +53,7 @@ func NewSocks5Plugin(params map[string]string) (p Plugin, err error) { func (sp *Socks5Plugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { defer conn.Close() wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - sp.Server.ServeConn(wrapConn) + _ = sp.Server.ServeConn(wrapConn) } func (sp *Socks5Plugin) Name() string { diff --git a/pkg/plugin/client/static_file.go b/pkg/plugin/client/static_file.go index 1eeea3ba..4d31ea53 100644 --- a/pkg/plugin/client/static_file.go +++ b/pkg/plugin/client/static_file.go @@ -19,9 +19,9 @@ import ( "net" "net/http" - frpNet "github.com/fatedier/frp/pkg/util/net" - "github.com/gorilla/mux" + + frpNet "github.com/fatedier/frp/pkg/util/net" ) const PluginStaticFile = "static_file" @@ -69,13 +69,15 @@ func NewStaticFilePlugin(params map[string]string) (Plugin, error) { sp.s = &http.Server{ Handler: router, } - go sp.s.Serve(listener) + go func() { + _ = sp.s.Serve(listener) + }() return sp, nil } func (sp *StaticFilePlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) - sp.l.PutConn(wrapConn) + _ = sp.l.PutConn(wrapConn) } func (sp *StaticFilePlugin) Name() string { diff --git a/pkg/plugin/client/unix_domain_socket.go b/pkg/plugin/client/unix_domain_socket.go index a85ada70..68902472 100644 --- a/pkg/plugin/client/unix_domain_socket.go +++ b/pkg/plugin/client/unix_domain_socket.go @@ -57,7 +57,9 @@ func (uds *UnixDomainSocketPlugin) Handle(conn io.ReadWriteCloser, realConn net. return } if len(extraBufToLocal) > 0 { - localConn.Write(extraBufToLocal) + if _, err := localConn.Write(extraBufToLocal); err != nil { + return + } } frpIo.Join(localConn, conn) diff --git a/pkg/plugin/server/http.go b/pkg/plugin/server/http.go index 5ca8c063..b120332d 100644 --- a/pkg/plugin/server/http.go +++ b/pkg/plugin/server/http.go @@ -43,12 +43,12 @@ type httpPlugin struct { } func NewHTTPPluginOptions(options HTTPPluginOptions) Plugin { - var url = fmt.Sprintf("%s%s", options.Addr, options.Path) + url := fmt.Sprintf("%s%s", options.Addr, options.Path) var client *http.Client if strings.HasPrefix(url, "https://") { tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: options.TLSVerify == false}, + TLSClientConfig: &tls.Config{InsecureSkipVerify: !options.TLSVerify}, } client = &http.Client{Transport: tr} } else { diff --git a/pkg/plugin/server/manager.go b/pkg/plugin/server/manager.go index 47d11d1c..5a8a309c 100644 --- a/pkg/plugin/server/manager.go +++ b/pkg/plugin/server/manager.go @@ -154,9 +154,8 @@ func (m *Manager) CloseProxy(content *CloseProxyContent) error { if len(errs) > 0 { return fmt.Errorf("send CloseProxy request to plugin errors: %s", strings.Join(errs, "; ")) - } else { - return nil } + return nil } func (m *Manager) Ping(content *PingContent) (*PingContent, error) { diff --git a/pkg/proto/udp/udp.go b/pkg/proto/udp/udp.go index 97f6ea40..7a11984b 100644 --- a/pkg/proto/udp/udp.go +++ b/pkg/proto/udp/udp.go @@ -20,10 +20,10 @@ import ( "sync" "time" - "github.com/fatedier/frp/pkg/msg" - "github.com/fatedier/golib/errors" "github.com/fatedier/golib/pool" + + "github.com/fatedier/frp/pkg/msg" ) func NewUDPPacket(buf []byte, laddr, raddr *net.UDPAddr) *msg.UDPPacket { @@ -47,7 +47,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UDPPacket, sendCh if err != nil { continue } - udpConn.WriteToUDP(buf, udpMsg.RemoteAddr) + _, _ = udpConn.WriteToUDP(buf, udpMsg.RemoteAddr) } }() @@ -70,9 +70,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UDPPacket, sendCh } func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UDPPacket, sendCh chan<- msg.Message, bufSize int) { - var ( - mu sync.RWMutex - ) + var mu sync.RWMutex udpConnMap := make(map[string]*net.UDPConn) // read from dstAddr and write to sendCh @@ -87,7 +85,7 @@ func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UDPPacket, sendCh chan<- buf := pool.GetBuf(bufSize) for { - udpConn.SetReadDeadline(time.Now().Add(30 * time.Second)) + _ = udpConn.SetReadDeadline(time.Now().Add(30 * time.Second)) n, _, err := udpConn.ReadFromUDP(buf) if err != nil { return diff --git a/pkg/transport/tls.go b/pkg/transport/tls.go index 38201f8e..02950cc5 100644 --- a/pkg/transport/tls.go +++ b/pkg/transport/tls.go @@ -19,7 +19,7 @@ func newCustomTLSKeyPair(certfile, keyfile string) (*tls.Certificate, error) { } func newRandomTLSKeyPair() *tls.Certificate { - key, err := rsa.GenerateKey(rand.Reader, 1024) + key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { panic(err) } @@ -58,7 +58,7 @@ func newCertPool(caPath string) (*x509.CertPool, error) { } func NewServerTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) { - var base = &tls.Config{} + base := &tls.Config{} if certPath == "" || keyPath == "" { // server will generate tls conf by itself @@ -87,7 +87,7 @@ func NewServerTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) { } func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Config, error) { - var base = &tls.Config{} + base := &tls.Config{} if certPath == "" || keyPath == "" { // client will not generate tls conf by itself diff --git a/pkg/util/log/log.go b/pkg/util/log/log.go index 1ddf4cdc..01a454d5 100644 --- a/pkg/util/log/log.go +++ b/pkg/util/log/log.go @@ -40,19 +40,19 @@ func SetLogFile(logWay string, logFile string, maxdays int64, disableLogColor bo if logWay == "console" { params := "" if disableLogColor { - params = fmt.Sprintf(`{"color": false}`) + params = `{"color": false}` } - Log.SetLogger("console", params) + _ = Log.SetLogger("console", params) } else { params := fmt.Sprintf(`{"filename": "%s", "maxdays": %d}`, logFile, maxdays) - Log.SetLogger("file", params) + _ = Log.SetLogger("file", params) } } // SetLogLevel set log level, default is warning // value: error, warning, info, debug, trace func SetLogLevel(logLevel string) { - level := 4 // warning + var level int switch logLevel { case "error": level = 3 @@ -65,7 +65,7 @@ func SetLogLevel(logLevel string) { case "trace": level = 8 default: - level = 4 + level = 4 // warning } Log.SetLevel(level) } diff --git a/pkg/util/net/kcp.go b/pkg/util/net/kcp.go index e9e0b126..77b6bfa7 100644 --- a/pkg/util/net/kcp.go +++ b/pkg/util/net/kcp.go @@ -32,8 +32,8 @@ func ListenKcp(address string) (l *KCPListener, err error) { if err != nil { return l, err } - listener.SetReadBuffer(4194304) - listener.SetWriteBuffer(4194304) + _ = listener.SetReadBuffer(4194304) + _ = listener.SetWriteBuffer(4194304) l = &KCPListener{ listener: listener, diff --git a/pkg/util/net/tls.go b/pkg/util/net/tls.go index 1bae196a..3aecb482 100644 --- a/pkg/util/net/tls.go +++ b/pkg/util/net/tls.go @@ -23,32 +23,30 @@ import ( gnet "github.com/fatedier/golib/net" ) -var ( - FRPTLSHeadByte = 0x17 -) +var FRPTLSHeadByte = 0x17 func CheckAndEnableTLSServerConnWithTimeout( c net.Conn, tlsConfig *tls.Config, tlsOnly bool, timeout time.Duration, ) (out net.Conn, isTLS bool, custom bool, err error) { - sc, r := gnet.NewSharedConnSize(c, 2) buf := make([]byte, 1) var n int - c.SetReadDeadline(time.Now().Add(timeout)) + _ = c.SetReadDeadline(time.Now().Add(timeout)) n, err = r.Read(buf) - c.SetReadDeadline(time.Time{}) + _ = c.SetReadDeadline(time.Time{}) if err != nil { return } - if n == 1 && int(buf[0]) == FRPTLSHeadByte { + switch { + case n == 1 && int(buf[0]) == FRPTLSHeadByte: out = tls.Server(c, tlsConfig) isTLS = true custom = true - } else if n == 1 && int(buf[0]) == 0x16 { + case n == 1 && int(buf[0]) == 0x16: out = tls.Server(sc, tlsConfig) isTLS = true - } else { + default: if tlsOnly { err = fmt.Errorf("non-TLS connection received on a TlsOnly server") return diff --git a/pkg/util/net/udp.go b/pkg/util/net/udp.go index 6689732e..82999a5f 100644 --- a/pkg/util/net/udp.go +++ b/pkg/util/net/udp.go @@ -55,7 +55,7 @@ func NewFakeUDPConn(l *UDPListener, laddr, raddr net.Addr) *FakeUDPConn { for { time.Sleep(5 * time.Second) fc.mu.RLock() - if time.Now().Sub(fc.lastActive) > 10*time.Second { + if time.Since(fc.lastActive) > 10*time.Second { fc.mu.RUnlock() fc.Close() break @@ -68,8 +68,7 @@ func NewFakeUDPConn(l *UDPListener, laddr, raddr net.Addr) *FakeUDPConn { func (c *FakeUDPConn) putPacket(content []byte) { defer func() { - if err := recover(); err != nil { - } + _ = recover() }() select { @@ -109,7 +108,7 @@ func (c *FakeUDPConn) Write(b []byte) (n int, err error) { LocalAddr: c.localAddr, RemoteAddr: c.remoteAddr, } - c.l.writeUDPPacket(packet) + _ = c.l.writeUDPPacket(packet) c.mu.Lock() c.lastActive = time.Now() @@ -208,7 +207,7 @@ func ListenUDP(bindAddr string, bindPort int) (l *UDPListener, err error) { } if addr, ok := packet.RemoteAddr.(*net.UDPAddr); ok { - readConn.WriteToUDP(packet.Buf, addr) + _, _ = readConn.WriteToUDP(packet.Buf, addr) } } }() diff --git a/pkg/util/net/websocket.go b/pkg/util/net/websocket.go index 4ec5c9fe..6a8d369c 100644 --- a/pkg/util/net/websocket.go +++ b/pkg/util/net/websocket.go @@ -9,9 +9,7 @@ import ( "golang.org/x/net/websocket" ) -var ( - ErrWebsocketListenerClosed = errors.New("websocket listener closed") -) +var ErrWebsocketListenerClosed = errors.New("websocket listener closed") const ( FrpWebsocketPath = "/~!frp" @@ -21,8 +19,7 @@ type WebsocketListener struct { ln net.Listener acceptCh chan net.Conn - server *http.Server - httpMutex *http.ServeMux + server *http.Server } // NewWebsocketListener to handle websocket connections @@ -47,7 +44,9 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) { Handler: muxer, } - go wl.server.Serve(ln) + go func() { + _ = wl.server.Serve(ln) + }() return } diff --git a/pkg/util/tcpmux/httpconnect.go b/pkg/util/tcpmux/httpconnect.go index 2639c493..e94ff4b2 100644 --- a/pkg/util/tcpmux/httpconnect.go +++ b/pkg/util/tcpmux/httpconnect.go @@ -22,9 +22,10 @@ import ( "net/http" "time" + gnet "github.com/fatedier/golib/net" + "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/vhost" - gnet "github.com/fatedier/golib/net" ) type HTTPConnectTCPMuxer struct { @@ -66,7 +67,11 @@ func (muxer *HTTPConnectTCPMuxer) sendConnectResponse(c net.Conn, reqInfo map[st if muxer.passthrough { return nil } - return util.OkResponse().Write(c) + res := util.OkResponse() + if res.Body != nil { + defer res.Body.Close() + } + return res.Write(c) } func (muxer *HTTPConnectTCPMuxer) getHostFromHTTPConnect(c net.Conn) (net.Conn, map[string]string, error) { @@ -82,11 +87,15 @@ func (muxer *HTTPConnectTCPMuxer) getHostFromHTTPConnect(c net.Conn) (net.Conn, reqInfoMap["Scheme"] = "tcp" reqInfoMap["HTTPUser"] = httpUser - var outConn net.Conn = c + outConn := c if muxer.passthrough { outConn = sc if muxer.authRequired && httpUser == "" { - util.ProxyUnauthorizedResponse().Write(c) + resp := util.ProxyUnauthorizedResponse() + if resp.Body != nil { + defer resp.Body.Close() + } + _ = resp.Write(c) outConn = c } } diff --git a/pkg/util/util/http.go b/pkg/util/util/http.go index 3b811734..d89af08b 100644 --- a/pkg/util/util/http.go +++ b/pkg/util/util/http.go @@ -60,10 +60,8 @@ func CanonicalHost(host string) (string, error) { return "", err } } - if strings.HasSuffix(host, ".") { - // Strip trailing dot from fully qualified domain names. - host = host[:len(host)-1] - } + // Strip trailing dot from fully qualified domain names. + host = strings.TrimSuffix(host, ".") return host, nil } diff --git a/pkg/util/util/util.go b/pkg/util/util/util.go index 032675fb..b13f9a77 100644 --- a/pkg/util/util/util.go +++ b/pkg/util/util/util.go @@ -44,7 +44,7 @@ func RandIDWithLen(idLen int) (id string, err error) { } func GetAuthKey(token string, timestamp int64) (key string) { - token = token + fmt.Sprintf("%d", timestamp) + token += fmt.Sprintf("%d", timestamp) md5Ctx := md5.New() md5Ctx.Write([]byte(token)) data := md5Ctx.Sum(nil) @@ -70,7 +70,8 @@ func ParseRangeNumbers(rangeStr string) (numbers []int64, err error) { numArray := strings.Split(numRangeStr, "-") // length: only 1 or 2 is correct rangeType := len(numArray) - if rangeType == 1 { + switch rangeType { + case 1: // single number singleNum, errRet := strconv.ParseInt(strings.TrimSpace(numArray[0]), 10, 64) if errRet != nil { @@ -78,7 +79,7 @@ func ParseRangeNumbers(rangeStr string) (numbers []int64, err error) { return } numbers = append(numbers, singleNum) - } else if rangeType == 2 { + case 2: // range numbers min, errRet := strconv.ParseInt(strings.TrimSpace(numArray[0]), 10, 64) if errRet != nil { @@ -97,7 +98,7 @@ func ParseRangeNumbers(rangeStr string) (numbers []int64, err error) { for i := min; i <= max; i++ { numbers = append(numbers, i) } - } else { + default: err = fmt.Errorf("range number is invalid") return } diff --git a/pkg/util/version/version.go b/pkg/util/version/version.go index b5eca317..b8b7be86 100644 --- a/pkg/util/version/version.go +++ b/pkg/util/version/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -var version string = "0.44.0" +var version = "0.44.0" func Full() string { return version diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index bfbd16ea..f2f08500 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -23,27 +23,26 @@ import ( "log" "net" "net/http" + "net/http/httputil" "net/url" "strings" "time" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/golib/pool" + frpLog "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/util" - frpIo "github.com/fatedier/golib/io" - - "github.com/fatedier/golib/pool" ) -var ( - ErrNoRouteFound = errors.New("no route found") -) +var ErrNoRouteFound = errors.New("no route found") type HTTPReverseProxyOptions struct { ResponseHeaderTimeoutS int64 } type HTTPReverseProxy struct { - proxy *ReverseProxy + proxy *httputil.ReverseProxy vhostRouter *Routers responseHeaderTimeout time.Duration @@ -57,7 +56,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * responseHeaderTimeout: time.Duration(option.ResponseHeaderTimeoutS) * time.Second, vhostRouter: vhostRouter, } - proxy := &ReverseProxy{ + proxy := &httputil.ReverseProxy{ // Modify incoming requests by route policies. Director: func(req *http.Request) { req.URL.Scheme = "http" @@ -81,7 +80,6 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * } else { req.URL.Host = req.Host } - }, // Create a connection to one proxy routed by route policy. Transport: &http.Transport{ @@ -114,7 +112,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) { frpLog.Warn("do http proxy request [host: %s] error: %v", req.Host, err) rw.WriteHeader(http.StatusNotFound) - rw.Write(getNotFoundPageContent()) + _, _ = rw.Write(getNotFoundPageContent()) }, } rp.proxy = proxy @@ -257,10 +255,28 @@ func (rp *HTTPReverseProxy) connectHandler(rw http.ResponseWriter, req *http.Req client.Close() return } - req.Write(remote) + _ = req.Write(remote) go frpIo.Join(remote, client) } +func parseBasicAuth(auth string) (username, password string, ok bool) { + const prefix = "Basic " + // Case insensitive prefix match. See Issue 22736. + if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) { + return + } + c, err := base64.StdEncoding.DecodeString(auth[len(prefix):]) + if err != nil { + return + } + cs := string(c) + s := strings.IndexByte(cs, ':') + if s < 0 { + return + } + return cs[:s], cs[s+1:], true +} + func (rp *HTTPReverseProxy) injectRequestInfoToCtx(req *http.Request) *http.Request { newctx := req.Context() newctx = context.WithValue(newctx, RouteInfoURL, req.URL.Path) diff --git a/pkg/util/vhost/resource.go b/pkg/util/vhost/resource.go index 446f40f9..14f6b2ad 100644 --- a/pkg/util/vhost/resource.go +++ b/pkg/util/vhost/resource.go @@ -24,9 +24,7 @@ import ( "github.com/fatedier/frp/pkg/util/version" ) -var ( - NotFoundPagePath = "" -) +var NotFoundPagePath = "" const ( NotFound = ` diff --git a/pkg/util/vhost/reverseproxy.go b/pkg/util/vhost/reverseproxy.go deleted file mode 100644 index 975f1d14..00000000 --- a/pkg/util/vhost/reverseproxy.go +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP reverse proxy handler - -package vhost - -import ( - "context" - "encoding/base64" - "fmt" - "io" - "log" - "net" - "net/http" - "net/textproto" - "net/url" - "strings" - "sync" - "time" - - "golang.org/x/net/http/httpguts" -) - -// ReverseProxy is an HTTP Handler that takes an incoming request and -// sends it to another server, proxying the response back to the -// client. -// -// ReverseProxy by default sets the client IP as the value of the -// X-Forwarded-For header. -// -// If an X-Forwarded-For header already exists, the client IP is -// appended to the existing values. As a special case, if the header -// exists in the Request.Header map but has a nil value (such as when -// set by the Director func), the X-Forwarded-For header is -// not modified. -// -// To prevent IP spoofing, be sure to delete any pre-existing -// X-Forwarded-For header coming from the client or -// an untrusted proxy. -type ReverseProxy struct { - // Director must be a function which modifies - // the request into a new request to be sent - // using Transport. Its response is then copied - // back to the original client unmodified. - // Director must not access the provided Request - // after returning. - Director func(*http.Request) - - // The transport used to perform proxy requests. - // If nil, http.DefaultTransport is used. - Transport http.RoundTripper - - // FlushInterval specifies the flush interval - // to flush to the client while copying the - // response body. - // If zero, no periodic flushing is done. - // A negative value means to flush immediately - // after each write to the client. - // The FlushInterval is ignored when ReverseProxy - // recognizes a response as a streaming response, or - // if its ContentLength is -1; for such responses, writes - // are flushed to the client immediately. - FlushInterval time.Duration - - // ErrorLog specifies an optional logger for errors - // that occur when attempting to proxy the request. - // If nil, logging is done via the log package's standard logger. - ErrorLog *log.Logger - - // BufferPool optionally specifies a buffer pool to - // get byte slices for use by io.CopyBuffer when - // copying HTTP response bodies. - BufferPool BufferPool - - // ModifyResponse is an optional function that modifies the - // Response from the backend. It is called if the backend - // returns a response at all, with any HTTP status code. - // If the backend is unreachable, the optional ErrorHandler is - // called without any call to ModifyResponse. - // - // If ModifyResponse returns an error, ErrorHandler is called - // with its error value. If ErrorHandler is nil, its default - // implementation is used. - ModifyResponse func(*http.Response) error - - // ErrorHandler is an optional function that handles errors - // reaching the backend or errors from ModifyResponse. - // - // If nil, the default is to log the provided error and return - // a 502 Status Bad Gateway response. - ErrorHandler func(http.ResponseWriter, *http.Request, error) -} - -// A BufferPool is an interface for getting and returning temporary -// byte slices for use by io.CopyBuffer. -type BufferPool interface { - Get() []byte - Put([]byte) -} - -func singleJoiningSlash(a, b string) string { - aslash := strings.HasSuffix(a, "/") - bslash := strings.HasPrefix(b, "/") - switch { - case aslash && bslash: - return a + b[1:] - case !aslash && !bslash: - return a + "/" + b - } - return a + b -} - -func joinURLPath(a, b *url.URL) (path, rawpath string) { - if a.RawPath == "" && b.RawPath == "" { - return singleJoiningSlash(a.Path, b.Path), "" - } - // Same as singleJoiningSlash, but uses EscapedPath to determine - // whether a slash should be added - apath := a.EscapedPath() - bpath := b.EscapedPath() - - aslash := strings.HasSuffix(apath, "/") - bslash := strings.HasPrefix(bpath, "/") - - switch { - case aslash && bslash: - return a.Path + b.Path[1:], apath + bpath[1:] - case !aslash && !bslash: - return a.Path + "/" + b.Path, apath + "/" + bpath - } - return a.Path + b.Path, apath + bpath -} - -// NewSingleHostReverseProxy returns a new ReverseProxy that routes -// URLs to the scheme, host, and base path provided in target. If the -// target's path is "/base" and the incoming request was for "/dir", -// the target request will be for /base/dir. -// NewSingleHostReverseProxy does not rewrite the Host header. -// To rewrite Host headers, use ReverseProxy directly with a custom -// Director policy. -func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { - targetQuery := target.RawQuery - director := func(req *http.Request) { - req.URL.Scheme = target.Scheme - req.URL.Host = target.Host - req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL) - if targetQuery == "" || req.URL.RawQuery == "" { - req.URL.RawQuery = targetQuery + req.URL.RawQuery - } else { - req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery - } - if _, ok := req.Header["User-Agent"]; !ok { - // explicitly disable User-Agent so it's not set to default value - req.Header.Set("User-Agent", "") - } - } - return &ReverseProxy{Director: director} -} - -func copyHeader(dst, src http.Header) { - for k, vv := range src { - for _, v := range vv { - dst.Add(k, v) - } - } -} - -// Hop-by-hop headers. These are removed when sent to the backend. -// As of RFC 7230, hop-by-hop headers are required to appear in the -// Connection header field. These are the headers defined by the -// obsoleted RFC 2616 (section 13.5.1) and are used for backward -// compatibility. -var hopHeaders = []string{ - "Connection", - "Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google - "Keep-Alive", - "Proxy-Authenticate", - "Proxy-Authorization", - "Te", // canonicalized version of "TE" - "Trailer", // not Trailers per URL above; https://www.rfc-editor.org/errata_search.php?eid=4522 - "Transfer-Encoding", - "Upgrade", -} - -func (p *ReverseProxy) defaultErrorHandler(rw http.ResponseWriter, req *http.Request, err error) { - p.logf("http: proxy error: %v", err) - rw.WriteHeader(http.StatusBadGateway) -} - -func (p *ReverseProxy) getErrorHandler() func(http.ResponseWriter, *http.Request, error) { - if p.ErrorHandler != nil { - return p.ErrorHandler - } - return p.defaultErrorHandler -} - -// modifyResponse conditionally runs the optional ModifyResponse hook -// and reports whether the request should proceed. -func (p *ReverseProxy) modifyResponse(rw http.ResponseWriter, res *http.Response, req *http.Request) bool { - if p.ModifyResponse == nil { - return true - } - if err := p.ModifyResponse(res); err != nil { - res.Body.Close() - p.getErrorHandler()(rw, req, err) - return false - } - return true -} - -func parseBasicAuth(auth string) (username, password string, ok bool) { - const prefix = "Basic " - // Case insensitive prefix match. See Issue 22736. - if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) { - return - } - c, err := base64.StdEncoding.DecodeString(auth[len(prefix):]) - if err != nil { - return - } - cs := string(c) - s := strings.IndexByte(cs, ':') - if s < 0 { - return - } - return cs[:s], cs[s+1:], true -} - -func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - transport := p.Transport - if transport == nil { - transport = http.DefaultTransport - } - - ctx := req.Context() - if cn, ok := rw.(http.CloseNotifier); ok { - var cancel context.CancelFunc - ctx, cancel = context.WithCancel(ctx) - defer cancel() - notifyChan := cn.CloseNotify() - go func() { - select { - case <-notifyChan: - cancel() - case <-ctx.Done(): - } - }() - } - - outreq := req.Clone(ctx) - if req.ContentLength == 0 { - outreq.Body = nil // Issue 16036: nil Body for http.Transport retries - } - if outreq.Header == nil { - outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate - } - - p.Director(outreq) - outreq.Close = false - - reqUpType := upgradeType(outreq.Header) - removeConnectionHeaders(outreq.Header) - - // Remove hop-by-hop headers to the backend. Especially - // important is "Connection" because we want a persistent - // connection, regardless of what the client sent to us. - for _, h := range hopHeaders { - hv := outreq.Header.Get(h) - if hv == "" { - continue - } - if h == "Te" && hv == "trailers" { - // Issue 21096: tell backend applications that - // care about trailer support that we support - // trailers. (We do, but we don't go out of - // our way to advertise that unless the - // incoming client request thought it was - // worth mentioning) - continue - } - outreq.Header.Del(h) - } - - // After stripping all the hop-by-hop connection headers above, add back any - // necessary for protocol upgrades, such as for websockets. - if reqUpType != "" { - outreq.Header.Set("Connection", "Upgrade") - outreq.Header.Set("Upgrade", reqUpType) - } - - if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { - // If we aren't the first proxy retain prior - // X-Forwarded-For information as a comma+space - // separated list and fold multiple headers into one. - prior, ok := outreq.Header["X-Forwarded-For"] - omit := ok && prior == nil // Issue 38079: nil now means don't populate the header - if len(prior) > 0 { - clientIP = strings.Join(prior, ", ") + ", " + clientIP - } - if !omit { - outreq.Header.Set("X-Forwarded-For", clientIP) - } - } - - res, err := transport.RoundTrip(outreq) - if err != nil { - p.getErrorHandler()(rw, outreq, err) - return - } - - // Deal with 101 Switching Protocols responses: (WebSocket, h2c, etc) - if res.StatusCode == http.StatusSwitchingProtocols { - if !p.modifyResponse(rw, res, outreq) { - return - } - p.handleUpgradeResponse(rw, outreq, res) - return - } - - removeConnectionHeaders(res.Header) - - for _, h := range hopHeaders { - res.Header.Del(h) - } - - if !p.modifyResponse(rw, res, outreq) { - return - } - - copyHeader(rw.Header(), res.Header) - - // The "Trailer" header isn't included in the Transport's response, - // at least for *http.Transport. Build it up from Trailer. - announcedTrailers := len(res.Trailer) - if announcedTrailers > 0 { - trailerKeys := make([]string, 0, len(res.Trailer)) - for k := range res.Trailer { - trailerKeys = append(trailerKeys, k) - } - rw.Header().Add("Trailer", strings.Join(trailerKeys, ", ")) - } - - rw.WriteHeader(res.StatusCode) - - err = p.copyResponse(rw, res.Body, p.flushInterval(res)) - if err != nil { - defer res.Body.Close() - // Since we're streaming the response, if we run into an error all we can do - // is abort the request. Issue 23643: ReverseProxy should use ErrAbortHandler - // on read error while copying body. - if !shouldPanicOnCopyError(req) { - p.logf("suppressing panic for copyResponse error in test; copy error: %v", err) - return - } - panic(http.ErrAbortHandler) - } - res.Body.Close() // close now, instead of defer, to populate res.Trailer - - if len(res.Trailer) > 0 { - // Force chunking if we saw a response trailer. - // This prevents net/http from calculating the length for short - // bodies and adding a Content-Length. - if fl, ok := rw.(http.Flusher); ok { - fl.Flush() - } - } - - if len(res.Trailer) == announcedTrailers { - copyHeader(rw.Header(), res.Trailer) - return - } - - for k, vv := range res.Trailer { - k = http.TrailerPrefix + k - for _, v := range vv { - rw.Header().Add(k, v) - } - } -} - -var inOurTests bool // whether we're in our own tests - -// shouldPanicOnCopyError reports whether the reverse proxy should -// panic with http.ErrAbortHandler. This is the right thing to do by -// default, but Go 1.10 and earlier did not, so existing unit tests -// weren't expecting panics. Only panic in our own tests, or when -// running under the HTTP server. -func shouldPanicOnCopyError(req *http.Request) bool { - if inOurTests { - // Our tests know to handle this panic. - return true - } - if req.Context().Value(http.ServerContextKey) != nil { - // We seem to be running under an HTTP server, so - // it'll recover the panic. - return true - } - // Otherwise act like Go 1.10 and earlier to not break - // existing tests. - return false -} - -// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h. -// See RFC 7230, section 6.1 -func removeConnectionHeaders(h http.Header) { - for _, f := range h["Connection"] { - for _, sf := range strings.Split(f, ",") { - if sf = textproto.TrimString(sf); sf != "" { - h.Del(sf) - } - } - } -} - -// flushInterval returns the p.FlushInterval value, conditionally -// overriding its value for a specific request/response. -func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration { - resCT := res.Header.Get("Content-Type") - - // For Server-Sent Events responses, flush immediately. - // The MIME type is defined in https://www.w3.org/TR/eventsource/#text-event-stream - if resCT == "text/event-stream" { - return -1 // negative means immediately - } - - // We might have the case of streaming for which Content-Length might be unset. - if res.ContentLength == -1 { - return -1 - } - - return p.FlushInterval -} - -func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval time.Duration) error { - if flushInterval != 0 { - if wf, ok := dst.(writeFlusher); ok { - mlw := &maxLatencyWriter{ - dst: wf, - latency: flushInterval, - } - defer mlw.stop() - - // set up initial timer so headers get flushed even if body writes are delayed - mlw.flushPending = true - mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush) - - dst = mlw - } - } - - var buf []byte - if p.BufferPool != nil { - buf = p.BufferPool.Get() - defer p.BufferPool.Put(buf) - } - _, err := p.copyBuffer(dst, src, buf) - return err -} - -// copyBuffer returns any write errors or non-EOF read errors, and the amount -// of bytes written. -func (p *ReverseProxy) copyBuffer(dst io.Writer, src io.Reader, buf []byte) (int64, error) { - if len(buf) == 0 { - buf = make([]byte, 32*1024) - } - var written int64 - for { - nr, rerr := src.Read(buf) - if rerr != nil && rerr != io.EOF && rerr != context.Canceled { - p.logf("httputil: ReverseProxy read error during body copy: %v", rerr) - } - if nr > 0 { - nw, werr := dst.Write(buf[:nr]) - if nw > 0 { - written += int64(nw) - } - if werr != nil { - return written, werr - } - if nr != nw { - return written, io.ErrShortWrite - } - } - if rerr != nil { - if rerr == io.EOF { - rerr = nil - } - return written, rerr - } - } -} - -func (p *ReverseProxy) logf(format string, args ...interface{}) { - if p.ErrorLog != nil { - p.ErrorLog.Printf(format, args...) - } else { - log.Printf(format, args...) - } -} - -type writeFlusher interface { - io.Writer - http.Flusher -} - -type maxLatencyWriter struct { - dst writeFlusher - latency time.Duration // non-zero; negative means to flush immediately - - mu sync.Mutex // protects t, flushPending, and dst.Flush - t *time.Timer - flushPending bool -} - -func (m *maxLatencyWriter) Write(p []byte) (n int, err error) { - m.mu.Lock() - defer m.mu.Unlock() - n, err = m.dst.Write(p) - if m.latency < 0 { - m.dst.Flush() - return - } - if m.flushPending { - return - } - if m.t == nil { - m.t = time.AfterFunc(m.latency, m.delayedFlush) - } else { - m.t.Reset(m.latency) - } - m.flushPending = true - return -} - -func (m *maxLatencyWriter) delayedFlush() { - m.mu.Lock() - defer m.mu.Unlock() - if !m.flushPending { // if stop was called but AfterFunc already started this goroutine - return - } - m.dst.Flush() - m.flushPending = false -} - -func (m *maxLatencyWriter) stop() { - m.mu.Lock() - defer m.mu.Unlock() - m.flushPending = false - if m.t != nil { - m.t.Stop() - } -} - -func upgradeType(h http.Header) string { - if !httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade") { - return "" - } - return strings.ToLower(h.Get("Upgrade")) -} - -func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) { - reqUpType := upgradeType(req.Header) - resUpType := upgradeType(res.Header) - if reqUpType != resUpType { - p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType)) - return - } - - hj, ok := rw.(http.Hijacker) - if !ok { - p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)) - return - } - backConn, ok := res.Body.(io.ReadWriteCloser) - if !ok { - p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body")) - return - } - - backConnCloseCh := make(chan bool) - go func() { - // Ensure that the cancelation of a request closes the backend. - // See issue https://golang.org/issue/35559. - select { - case <-req.Context().Done(): - case <-backConnCloseCh: - } - backConn.Close() - }() - - defer close(backConnCloseCh) - - conn, brw, err := hj.Hijack() - if err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err)) - return - } - defer conn.Close() - - copyHeader(rw.Header(), res.Header) - - res.Header = rw.Header() - res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above - if err := res.Write(brw); err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err)) - return - } - if err := brw.Flush(); err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("response flush: %v", err)) - return - } - errc := make(chan error, 1) - spc := switchProtocolCopier{user: conn, backend: backConn} - go spc.copyToBackend(errc) - go spc.copyFromBackend(errc) - <-errc - return -} - -// switchProtocolCopier exists so goroutines proxying data back and -// forth have nice names in stacks. -type switchProtocolCopier struct { - user, backend io.ReadWriter -} - -func (c switchProtocolCopier) copyFromBackend(errc chan<- error) { - _, err := io.Copy(c.user, c.backend) - errc <- err -} - -func (c switchProtocolCopier) copyToBackend(errc chan<- error) { - _, err := io.Copy(c.backend, c.user) - errc <- err -} diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 768420a4..281e164b 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -7,9 +7,7 @@ import ( "sync" ) -var ( - ErrRouterConfigConflict = errors.New("router config conflict") -) +var ErrRouterConfigConflict = errors.New("router config conflict") type routerByHTTPUser map[string][]*Router @@ -133,9 +131,11 @@ 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/vhost/vhost.go b/pkg/util/vhost/vhost.go index 2957cec4..50690052 100644 --- a/pkg/util/vhost/vhost.go +++ b/pkg/util/vhost/vhost.go @@ -19,11 +19,11 @@ import ( "strings" "time" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/util/log" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/xlog" - - "github.com/fatedier/golib/errors" ) type RouteInfo string @@ -36,10 +36,12 @@ const ( RouteInfoURLHost RouteInfo = "urlHost" ) -type muxFunc func(net.Conn) (net.Conn, map[string]string, error) -type httpAuthFunc func(net.Conn, string, string, string) (bool, error) -type hostRewriteFunc func(net.Conn, string) (net.Conn, error) -type successFunc func(net.Conn, map[string]string) error +type ( + muxFunc func(net.Conn) (net.Conn, map[string]string, error) + httpAuthFunc func(net.Conn, string, string, string) (bool, error) + hostRewriteFunc func(net.Conn, string) (net.Conn, error) + successFunc func(net.Conn, map[string]string) error +) // Muxer is only used for https and tcpmux proxy. type Muxer struct { @@ -60,7 +62,6 @@ func NewMuxer( rewriteFunc hostRewriteFunc, timeout time.Duration, ) (mux *Muxer, err error) { - mux = &Muxer{ listener: listener, timeout: timeout, @@ -111,9 +112,8 @@ func (v *Muxer) Listen(ctx context.Context, cfg *RouteConfig) (l *Listener, err } func (v *Muxer) getListener(name, path, httpUser string) (*Listener, bool) { - findRouter := func(inName, inPath, inHTTPUser string) (*Listener, bool) { - vr, ok := v.registryRouter.Get(inName, inPath, httpUser) + vr, ok := v.registryRouter.Get(inName, inPath, inHTTPUser) if ok { return vr.payload.(*Listener), true } @@ -167,14 +167,14 @@ func (v *Muxer) run() { func (v *Muxer) handle(c net.Conn) { if err := c.SetDeadline(time.Now().Add(v.timeout)); err != nil { - c.Close() + _ = c.Close() return } sConn, reqInfoMap, err := v.vhostFunc(c) if err != nil { log.Debug("get hostname from http/https request error: %v", err) - c.Close() + _ = c.Close() return } @@ -184,9 +184,12 @@ func (v *Muxer) handle(c net.Conn) { l, ok := v.getListener(name, path, httpUser) if !ok { res := notFoundResponse() - res.Write(c) + if res.Body != nil { + defer res.Body.Close() + } + _ = res.Write(c) log.Debug("http request for host [%s] path [%s] httpUser [%s] not found", name, path, httpUser) - c.Close() + _ = c.Close() return } @@ -194,7 +197,7 @@ func (v *Muxer) handle(c net.Conn) { if v.successFunc != nil { if err := v.successFunc(c, reqInfoMap); err != nil { xl.Info("success func failure on vhost connection: %v", err) - c.Close() + _ = c.Close() return } } @@ -203,17 +206,20 @@ func (v *Muxer) handle(c net.Conn) { // then verify user access if l.mux.authFunc != nil && l.userName != "" && l.passWord != "" { bAccess, err := l.mux.authFunc(c, l.userName, l.passWord, reqInfoMap["Authorization"]) - if bAccess == false || err != nil { + if !bAccess || err != nil { xl.Debug("check http Authorization failed") res := noAuthResponse() - res.Write(c) - c.Close() + if res.Body != nil { + defer res.Body.Close() + } + _ = res.Write(c) + _ = c.Close() return } } if err = sConn.SetDeadline(time.Time{}); err != nil { - c.Close() + _ = c.Close() return } c = sConn diff --git a/server/control.go b/server/control.go index 197c94de..3fcd3ae4 100644 --- a/server/control.go +++ b/server/control.go @@ -23,6 +23,10 @@ import ( "sync" "time" + "github.com/fatedier/golib/control/shutdown" + "github.com/fatedier/golib/crypto" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" @@ -35,10 +39,6 @@ import ( "github.com/fatedier/frp/server/controller" "github.com/fatedier/frp/server/metrics" "github.com/fatedier/frp/server/proxy" - - "github.com/fatedier/golib/control/shutdown" - "github.com/fatedier/golib/crypto" - "github.com/fatedier/golib/errors" ) type ControlManager struct { @@ -154,7 +154,6 @@ func NewControl( loginMsg *msg.Login, serverCfg config.ServerCommonConf, ) *Control { - poolCount := loginMsg.PoolCount if poolCount > int(serverCfg.MaxPoolCount) { poolCount = int(serverCfg.MaxPoolCount) @@ -193,7 +192,7 @@ func (ctl *Control) Start() { ServerUDPPort: ctl.serverCfg.BindUDPPort, Error: "", } - msg.WriteMsg(ctl.conn, loginRespMsg) + _ = msg.WriteMsg(ctl.conn, loginRespMsg) go ctl.writer() for i := 0; i < ctl.poolCount; i++ { @@ -270,7 +269,7 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) { } // When we get a work connection from pool, replace it with a new one. - errors.PanicToError(func() { + _ = errors.PanicToError(func() { ctl.sendCh <- &msg.ReqWorkConn{} }) return @@ -388,7 +387,7 @@ func (ctl *Control) stoper() { }, } go func() { - ctl.pluginManager.CloseProxy(notifyContent) + _ = ctl.pluginManager.CloseProxy(notifyContent) }() } @@ -467,7 +466,7 @@ func (ctl *Control) manager() { } ctl.sendCh <- resp case *msg.CloseProxy: - ctl.CloseProxy(m) + _ = ctl.CloseProxy(m) xl.Info("close proxy [%s] success", m.ProxyName) case *msg.Ping: content := &plugin.PingContent{ @@ -528,13 +527,13 @@ func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err err = fmt.Errorf("exceed the max_ports_per_client") return } - ctl.portsUsedNum = ctl.portsUsedNum + pxy.GetUsedPortsNum() + ctl.portsUsedNum += pxy.GetUsedPortsNum() ctl.mu.Unlock() defer func() { if err != nil { ctl.mu.Lock() - ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum() + ctl.portsUsedNum -= pxy.GetUsedPortsNum() ctl.mu.Unlock() } }() @@ -570,7 +569,7 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) { } if ctl.serverCfg.MaxPortsPerClient > 0 { - ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum() + ctl.portsUsedNum -= pxy.GetUsedPortsNum() } pxy.Close() ctl.pxyManager.Del(pxy.GetName()) @@ -590,7 +589,7 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) { }, } go func() { - ctl.pluginManager.CloseProxy(notifyContent) + _ = ctl.pluginManager.CloseProxy(notifyContent) }() return diff --git a/server/dashboard.go b/server/dashboard.go index 68e99f8a..02c86325 100644 --- a/server/dashboard.go +++ b/server/dashboard.go @@ -21,11 +21,11 @@ import ( "net/http/pprof" "time" - "github.com/fatedier/frp/assets" - frpNet "github.com/fatedier/frp/pkg/util/net" - "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" + + "github.com/fatedier/frp/assets" + frpNet "github.com/fatedier/frp/pkg/util/net" ) var ( @@ -92,6 +92,8 @@ func (svr *Service) RunDashboardServer(address string) (err error) { } ln = tls.NewListener(ln, tlsCfg) } - go server.Serve(ln) + go func() { + _ = server.Serve(ln) + }() return } diff --git a/server/dashboard_api.go b/server/dashboard_api.go index 7d159c7a..6f7ecfd7 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -18,13 +18,13 @@ import ( "encoding/json" "net/http" + "github.com/gorilla/mux" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/consts" "github.com/fatedier/frp/pkg/metrics/mem" "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/version" - - "github.com/gorilla/mux" ) type GeneralResponse struct { @@ -63,7 +63,7 @@ func (svr *Service) APIServerInfo(w http.ResponseWriter, r *http.Request) { log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() @@ -179,7 +179,7 @@ func (svr *Service) APIProxyByType(w http.ResponseWriter, r *http.Request) { log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() log.Info("Http request: [%s]", r.URL.Path) @@ -245,12 +245,12 @@ func (svr *Service) APIProxyByTypeAndName(w http.ResponseWriter, r *http.Request log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() log.Info("Http request: [%s]", r.URL.Path) - proxyStatsResp := GetProxyStatsResp{} + var proxyStatsResp GetProxyStatsResp proxyStatsResp, res.Code, res.Msg = svr.getProxyStatsByTypeAndName(proxyType, name) if res.Code != 200 { return @@ -313,7 +313,7 @@ func (svr *Service) APIProxyTraffic(w http.ResponseWriter, r *http.Request) { log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code) w.WriteHeader(res.Code) if len(res.Msg) > 0 { - w.Write([]byte(res.Msg)) + _, _ = w.Write([]byte(res.Msg)) } }() log.Info("Http request: [%s]", r.URL.Path) diff --git a/server/group/http.go b/server/group/http.go index fb00f0c7..7e081eb5 100644 --- a/server/group/http.go +++ b/server/group/http.go @@ -31,7 +31,6 @@ func (ctl *HTTPGroupController) Register( proxyName, group, groupKey string, routeConfig vhost.RouteConfig, ) (err error) { - indexKey := group ctl.mu.Lock() g, ok := ctl.groups[indexKey] @@ -86,7 +85,6 @@ func (g *HTTPGroup) Register( proxyName, group, groupKey string, routeConfig vhost.RouteConfig, ) (err error) { - g.mu.Lock() defer g.mu.Unlock() if len(g.createFuncs) == 0 { @@ -152,7 +150,7 @@ func (g *HTTPGroup) createConn(remoteAddr string) (net.Conn, error) { routeByHTTPUser := g.routeByHTTPUser if len(g.pxyNames) > 0 { name := g.pxyNames[int(newIndex)%len(g.pxyNames)] - f, _ = g.createFuncs[name] + f = g.createFuncs[name] } g.mu.RUnlock() diff --git a/server/group/tcp.go b/server/group/tcp.go index c7fd2b27..c0dcd5f7 100644 --- a/server/group/tcp.go +++ b/server/group/tcp.go @@ -19,9 +19,9 @@ import ( "strconv" "sync" - "github.com/fatedier/frp/server/ports" - gerr "github.com/fatedier/golib/errors" + + "github.com/fatedier/frp/server/ports" ) // TCPGroupCtl manage all TCPGroups @@ -44,8 +44,8 @@ func NewTCPGroupCtl(portManager *ports.Manager) *TCPGroupCtl { // Listen is the wrapper for TCPGroup's Listen // If there are no group, we will create one here func (tgc *TCPGroupCtl) Listen(proxyName string, group string, groupKey string, - addr string, port int) (l net.Listener, realPort int, err error) { - + addr string, port int, +) (l net.Listener, realPort int, err error) { tgc.mu.Lock() tcpGroup, ok := tgc.groups[group] if !ok { @@ -73,7 +73,6 @@ type TCPGroup struct { realPort int acceptCh chan net.Conn - index uint64 tcpLn net.Listener lns []*TCPGroupListener ctl *TCPGroupCtl diff --git a/server/group/tcpmux.go b/server/group/tcpmux.go index fd805d91..2da85cee 100644 --- a/server/group/tcpmux.go +++ b/server/group/tcpmux.go @@ -20,11 +20,11 @@ import ( "net" "sync" + gerr "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/consts" "github.com/fatedier/frp/pkg/util/tcpmux" "github.com/fatedier/frp/pkg/util/vhost" - - gerr "github.com/fatedier/golib/errors" ) // TCPMuxGroupCtl manage all TCPMuxGroups @@ -51,7 +51,6 @@ func (tmgc *TCPMuxGroupCtl) Listen( multiplexer, group, groupKey string, routeConfig vhost.RouteConfig, ) (l net.Listener, err error) { - tmgc.mu.Lock() tcpMuxGroup, ok := tmgc.groups[group] if !ok { @@ -84,7 +83,6 @@ type TCPMuxGroup struct { routeByHTTPUser string acceptCh chan net.Conn - index uint64 tcpMuxLn net.Listener lns []*TCPMuxGroupListener ctl *TCPMuxGroupCtl @@ -108,7 +106,6 @@ func (tmg *TCPMuxGroup) HTTPConnectListen( group, groupKey string, routeConfig vhost.RouteConfig, ) (ln *TCPMuxGroupListener, err error) { - tmg.mu.Lock() defer tmg.mu.Unlock() if len(tmg.lns) == 0 { diff --git a/server/proxy/http.go b/server/proxy/http.go index e0e2f23c..e70cb65f 100644 --- a/server/proxy/http.go +++ b/server/proxy/http.go @@ -19,13 +19,13 @@ import ( "net" "strings" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/frp/pkg/config" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" "github.com/fatedier/frp/pkg/util/vhost" "github.com/fatedier/frp/server/metrics" - - frpIo "github.com/fatedier/golib/io" ) type HTTPProxy struct { @@ -89,7 +89,7 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) { pxy.rc.HTTPReverseProxy.UnRegister(tmpRouteConfig) }) } - addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHTTPPort))) + addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPPort)) xl.Info("http proxy listen for host [%s] location [%s] group [%s], routeByHTTPUser [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group, pxy.cfg.RouteByHTTPUser) } diff --git a/server/proxy/https.go b/server/proxy/https.go index cd566462..42ecf35d 100644 --- a/server/proxy/https.go +++ b/server/proxy/https.go @@ -62,7 +62,7 @@ func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) { } xl.Info("https proxy listen for host [%s]", routeConfig.Domain) pxy.listeners = append(pxy.listeners, l) - addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHTTPSPort))) + addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPSPort)) } pxy.startListenHandler(pxy, HandleUserTCPConnection) diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index 43c2c74e..808d9316 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -23,6 +23,8 @@ import ( "sync" "time" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" plugin "github.com/fatedier/frp/pkg/plugin/server" @@ -30,8 +32,6 @@ import ( "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" "github.com/fatedier/frp/server/metrics" - - frpIo "github.com/fatedier/golib/io" ) type GetWorkConnFn func() (net.Conn, error) @@ -184,8 +184,8 @@ func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, net.Conn, } func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.ResourceController, poolCount int, - getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf) (pxy Proxy, err error) { - + getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf, +) (pxy Proxy, err error) { xl := xlog.FromContextSafe(ctx).Spawn().AppendPrefix(pxyConf.GetBaseInfo().ProxyName) basePxy := BaseProxy{ name: pxyConf.GetBaseInfo().ProxyName, diff --git a/server/proxy/udp.go b/server/proxy/udp.go index 9e3c0675..53865540 100644 --- a/server/proxy/udp.go +++ b/server/proxy/udp.go @@ -22,14 +22,14 @@ import ( "strconv" "time" + "github.com/fatedier/golib/errors" + frpIo "github.com/fatedier/golib/io" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/proto/udp" frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/server/metrics" - - "github.com/fatedier/golib/errors" - frpIo "github.com/fatedier/golib/io" ) type UDPProxy struct { @@ -98,18 +98,20 @@ func (pxy *UDPProxy) Run() (remoteAddr string, err error) { ) xl.Trace("loop waiting message from udp workConn") // client will send heartbeat in workConn for keeping alive - conn.SetReadDeadline(time.Now().Add(time.Duration(60) * time.Second)) + _ = conn.SetReadDeadline(time.Now().Add(time.Duration(60) * time.Second)) if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil { xl.Warn("read from workConn for udp error: %v", errRet) - conn.Close() + _ = conn.Close() // notify proxy to start a new work connection // ignore error here, it means the proxy is closed - errors.PanicToError(func() { + _ = errors.PanicToError(func() { pxy.checkCloseCh <- 1 }) return } - conn.SetReadDeadline(time.Time{}) + if err := conn.SetReadDeadline(time.Time{}); err != nil { + xl.Warn("set read deadline error: %v", err) + } switch m := rawMsg.(type) { case *msg.Ping: xl.Trace("udp work conn get ping message") diff --git a/server/proxy/xtcp.go b/server/proxy/xtcp.go index 317a3d48..a1b45d54 100644 --- a/server/proxy/xtcp.go +++ b/server/proxy/xtcp.go @@ -17,10 +17,10 @@ package proxy import ( "fmt" + "github.com/fatedier/golib/errors" + "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" - - "github.com/fatedier/golib/errors" ) type XTCPProxy struct { @@ -91,7 +91,7 @@ func (pxy *XTCPProxy) GetConf() config.ProxyConf { func (pxy *XTCPProxy) Close() { pxy.BaseProxy.Close() pxy.rc.NatHoleController.CloseClient(pxy.GetName()) - errors.PanicToError(func() { + _ = errors.PanicToError(func() { close(pxy.closeCh) }) } diff --git a/server/service.go b/server/service.go index c3d398b2..68308270 100644 --- a/server/service.go +++ b/server/service.go @@ -26,6 +26,9 @@ import ( "strconv" "time" + "github.com/fatedier/golib/net/mux" + fmux "github.com/hashicorp/yamux" + "github.com/fatedier/frp/assets" "github.com/fatedier/frp/pkg/auth" "github.com/fatedier/frp/pkg/config" @@ -47,9 +50,6 @@ import ( "github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/proxy" "github.com/fatedier/frp/server/visitor" - - "github.com/fatedier/golib/net/mux" - fmux "github.com/hashicorp/yamux" ) const ( @@ -127,26 +127,26 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.TCPMuxHTTPConnectPort)) l, err = net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create server listener error, %v", err) + err = fmt.Errorf("create server listener error, %v", err) return } svr.rc.TCPMuxHTTPConnectMuxer, err = tcpmux.NewHTTPConnectTCPMuxer(l, cfg.TCPMuxPassthrough, vhostReadWriteTimeout) if err != nil { - err = fmt.Errorf("Create vhost tcpMuxer error, %v", err) + err = fmt.Errorf("create vhost tcpMuxer error, %v", err) return } log.Info("tcpmux httpconnect multiplexer listen on %s, passthough: %v", address, cfg.TCPMuxPassthrough) } // Init all plugins - plugin_names := make([]string, 0, len(cfg.HTTPPlugins)) + pluginNames := make([]string, 0, len(cfg.HTTPPlugins)) for n := range cfg.HTTPPlugins { - plugin_names = append(plugin_names, n) + pluginNames = append(pluginNames, n) } - sort.Strings(plugin_names) + sort.Strings(pluginNames) - for _, name := range plugin_names { + for _, name := range pluginNames { svr.pluginManager.Register(plugin.NewHTTPPluginOptions(cfg.HTTPPlugins[name])) log.Info("plugin [%s] has been registered", name) } @@ -181,13 +181,15 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindPort)) ln, err := net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create server listener error, %v", err) + err = fmt.Errorf("create server listener error, %v", err) return } svr.muxer = mux.NewMux(ln) svr.muxer.SetKeepAlive(time.Duration(cfg.TCPKeepAlive) * time.Second) - go svr.muxer.Serve() + go func() { + _ = svr.muxer.Serve() + }() ln = svr.muxer.DefaultListener() svr.listener = ln @@ -198,7 +200,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort)) svr.kcpListener, err = frpNet.ListenKcp(address) if err != nil { - err = fmt.Errorf("Listen on kcp address udp %s error: %v", address, err) + err = fmt.Errorf("listen on kcp address udp %s error: %v", address, err) return } log.Info("frps kcp listen on udp %s", address) @@ -229,11 +231,13 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { } else { l, err = net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create vhost http listener error, %v", err) + err = fmt.Errorf("create vhost http listener error, %v", err) return } } - go server.Serve(l) + go func() { + _ = server.Serve(l) + }() log.Info("http service listen on %s", address) } @@ -246,7 +250,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort)) l, err = net.Listen("tcp", address) if err != nil { - err = fmt.Errorf("Create server listener error, %v", err) + err = fmt.Errorf("create server listener error, %v", err) return } log.Info("https service listen on %s", address) @@ -254,7 +258,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout) if err != nil { - err = fmt.Errorf("Create vhost httpsMuxer error, %v", err) + err = fmt.Errorf("create vhost httpsMuxer error, %v", err) return } } @@ -271,7 +275,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindUDPPort)) nc, err = nathole.NewController(address) if err != nil { - err = fmt.Errorf("Create nat hole controller error, %v", err) + err = fmt.Errorf("create nat hole controller error, %v", err) return } svr.rc.NatHoleController = nc @@ -287,7 +291,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) { address := net.JoinHostPort(cfg.DashboardAddr, strconv.Itoa(cfg.DashboardPort)) err = svr.RunDashboardServer(address) if err != nil { - err = fmt.Errorf("Create dashboard web server error, %v", err) + err = fmt.Errorf("create dashboard web server error, %v", err) return } log.Info("Dashboard listen on %s", address) @@ -324,13 +328,13 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { err error ) - conn.SetReadDeadline(time.Now().Add(connReadTimeout)) + _ = conn.SetReadDeadline(time.Now().Add(connReadTimeout)) if rawMsg, err = msg.ReadMsg(conn); err != nil { log.Trace("Failed to read message: %v", err) conn.Close() return } - conn.SetReadDeadline(time.Time{}) + _ = conn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { case *msg.Login: @@ -349,7 +353,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { // Otherwise send success message in control's work goroutine. if err != nil { xl.Warn("register control error: %v", err) - msg.WriteMsg(conn, &msg.LoginResp{ + _ = msg.WriteMsg(conn, &msg.LoginResp{ Version: version.Full(), Error: util.GenerateResponseErrorString("register control error", err, svr.cfg.DetailedErrorsToClient), }) @@ -362,13 +366,13 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { case *msg.NewVisitorConn: if err = svr.RegisterVisitorConn(conn, m); err != nil { xl.Warn("register visitor conn error: %v", err) - msg.WriteMsg(conn, &msg.NewVisitorConnResp{ + _ = msg.WriteMsg(conn, &msg.NewVisitorConnResp{ ProxyName: m.ProxyName, Error: util.GenerateResponseErrorString("register visitor conn error", err, svr.cfg.DetailedErrorsToClient), }) conn.Close() } else { - msg.WriteMsg(conn, &msg.NewVisitorConnResp{ + _ = msg.WriteMsg(conn, &msg.NewVisitorConnResp{ ProxyName: m.ProxyName, Error: "", }) @@ -504,7 +508,7 @@ func (svr *Service) RegisterWorkConn(workConn net.Conn, newMsg *msg.NewWorkConn) } if err != nil { xl.Warn("invalid NewWorkConn with run id [%s]", newMsg.RunID) - msg.WriteMsg(workConn, &msg.StartWorkConn{ + _ = msg.WriteMsg(workConn, &msg.StartWorkConn{ Error: util.GenerateResponseErrorString("invalid NewWorkConn", err, ctl.serverCfg.DetailedErrorsToClient), }) return fmt.Errorf("invalid NewWorkConn with run id [%s]", newMsg.RunID) diff --git a/server/visitor/visitor.go b/server/visitor/visitor.go index 4796b416..70f603b2 100644 --- a/server/visitor/visitor.go +++ b/server/visitor/visitor.go @@ -20,10 +20,10 @@ import ( "net" "sync" + frpIo "github.com/fatedier/golib/io" + frpNet "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" - - frpIo "github.com/fatedier/golib/io" ) // Manager for visitor listeners. @@ -57,8 +57,8 @@ func (vm *Manager) Listen(name string, sk string) (l *frpNet.CustomListener, err } func (vm *Manager) NewConn(name string, conn net.Conn, timestamp int64, signKey string, - useEncryption bool, useCompression bool) (err error) { - + useEncryption bool, useCompression bool, +) (err error) { vm.mu.RLock() defer vm.mu.RUnlock() diff --git a/test/e2e/basic/basic.go b/test/e2e/basic/basic.go index 13f17168..1f1b2007 100644 --- a/test/e2e/basic/basic.go +++ b/test/e2e/basic/basic.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" @@ -12,18 +14,16 @@ import ( "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Basic]", func() { +var _ = ginkgo.Describe("[Feature: Basic]", func() { f := framework.NewDefaultFramework() - Describe("TCP && UDP", func() { + ginkgo.Describe("TCP && UDP", func() { types := []string{"tcp", "udp"} for _, t := range types { proxyType := t - It(fmt.Sprintf("Expose a %s echo server", strings.ToUpper(proxyType)), func() { + ginkgo.It(fmt.Sprintf("Expose a %s echo server", strings.ToUpper(proxyType)), func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -93,8 +93,8 @@ var _ = Describe("[Feature: Basic]", func() { } }) - Describe("HTTP", func() { - It("proxy to HTTP server", func() { + ginkgo.Describe("HTTP", func() { + ginkgo.It("proxy to HTTP server", func() { serverConf := consts.DefaultServerConfig vhostHTTPPort := f.AllocPort() serverConf += fmt.Sprintf(` @@ -175,8 +175,8 @@ var _ = Describe("[Feature: Basic]", func() { }) }) - Describe("HTTPS", func() { - It("proxy to HTTPS server", func() { + ginkgo.Describe("HTTPS", func() { + ginkgo.It("proxy to HTTPS server", func() { serverConf := consts.DefaultServerConfig vhostHTTPSPort := f.AllocPort() serverConf += fmt.Sprintf(` @@ -237,7 +237,7 @@ var _ = Describe("[Feature: Basic]", func() { framework.ExpectNoError(err) localServer := httpserver.New( httpserver.WithBindPort(localPort), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), httpserver.WithResponse([]byte("test")), ) f.RunServer("", localServer) @@ -275,11 +275,11 @@ var _ = Describe("[Feature: Basic]", func() { }) }) - Describe("STCP && SUDP", func() { + ginkgo.Describe("STCP && SUDP", func() { types := []string{"stcp", "sudp"} for _, t := range types { proxyType := t - It(fmt.Sprintf("Expose echo server with %s", strings.ToUpper(proxyType)), func() { + ginkgo.It(fmt.Sprintf("Expose echo server with %s", strings.ToUpper(proxyType)), func() { serverConf := consts.DefaultServerConfig clientServerConf := consts.DefaultClientConfig clientVisitorConf := consts.DefaultClientConfig @@ -381,8 +381,8 @@ var _ = Describe("[Feature: Basic]", func() { } }) - Describe("TCPMUX", func() { - It("Type tcpmux", func() { + ginkgo.Describe("TCPMUX", func() { + ginkgo.It("Type tcpmux", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig diff --git a/test/e2e/basic/client.go b/test/e2e/basic/client.go index 8d370928..10489d49 100644 --- a/test/e2e/basic/client.go +++ b/test/e2e/basic/client.go @@ -6,18 +6,18 @@ import ( "strings" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/request" clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: ClientManage]", func() { +var _ = ginkgo.Describe("[Feature: ClientManage]", func() { f := framework.NewDefaultFramework() - It("Update && Reload API", func() { + ginkgo.It("Update && Reload API", func() { serverConf := consts.DefaultServerConfig adminPort := f.AllocPort() @@ -62,7 +62,9 @@ var _ = Describe("[Feature: ClientManage]", func() { // change p2 port and remove p3 proxy newClientConf := strings.ReplaceAll(conf, strconv.Itoa(p2Port), strconv.Itoa(newP2Port)) p3Index := strings.Index(newClientConf, "[p3]") - newClientConf = newClientConf[:p3Index] + if p3Index >= 0 { + newClientConf = newClientConf[:p3Index] + } err = client.UpdateConfig(newClientConf) framework.ExpectNoError(err) @@ -77,7 +79,7 @@ var _ = Describe("[Feature: ClientManage]", func() { framework.NewRequestExpect(f).Port(p3Port).Explain("p3 port").ExpectError(true).Ensure() }) - It("healthz", func() { + ginkgo.It("healthz", func() { serverConf := consts.DefaultServerConfig dashboardPort := f.AllocPort() @@ -99,5 +101,4 @@ var _ = Describe("[Feature: ClientManage]", func() { }).Port(dashboardPort). Ensure(framework.ExpectResponseCode(401)) }) - }) diff --git a/test/e2e/basic/client_server.go b/test/e2e/basic/client_server.go index c19077c4..210500ba 100644 --- a/test/e2e/basic/client_server.go +++ b/test/e2e/basic/client_server.go @@ -4,12 +4,12 @@ import ( "fmt" "strings" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/cert" "github.com/fatedier/frp/test/e2e/pkg/port" - - . "github.com/onsi/ginkgo" ) type generalTestConfigures struct { @@ -54,15 +54,15 @@ func runClientServerTest(f *framework.Framework, configures *generalTestConfigur // defineClientServerTest test a normal tcp and udp proxy with specified TestConfigures. func defineClientServerTest(desc string, f *framework.Framework, configures *generalTestConfigures) { - It(desc, func() { + ginkgo.It(desc, func() { runClientServerTest(f, configures) }) } -var _ = Describe("[Feature: Client-Server]", func() { +var _ = ginkgo.Describe("[Feature: Client-Server]", func() { f := framework.NewDefaultFramework() - Describe("Protocol", func() { + ginkgo.Describe("Protocol", func() { supportProtocols := []string{"tcp", "kcp", "websocket"} for _, protocol := range supportProtocols { configures := &generalTestConfigures{ @@ -76,7 +76,7 @@ var _ = Describe("[Feature: Client-Server]", func() { } }) - Describe("Authentication", func() { + ginkgo.Describe("Authentication", func() { defineClientServerTest("Token Correct", f, &generalTestConfigures{ server: "token = 123456", client: "token = 123456", @@ -89,7 +89,7 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - Describe("TLS", func() { + ginkgo.Describe("TLS", func() { supportProtocols := []string{"tcp", "kcp", "websocket"} for _, protocol := range supportProtocols { tmp := protocol @@ -114,7 +114,7 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - Describe("TLS with custom certificate", func() { + ginkgo.Describe("TLS with custom certificate", func() { supportProtocols := []string{"tcp", "kcp", "websocket"} var ( @@ -122,7 +122,7 @@ var _ = Describe("[Feature: Client-Server]", func() { serverCrtPath, serverKeyPath string clientCrtPath, clientKeyPath string ) - JustBeforeEach(func() { + ginkgo.JustBeforeEach(func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("0.0.0.0") framework.ExpectNoError(err) @@ -131,7 +131,8 @@ var _ = Describe("[Feature: Client-Server]", func() { serverCrtPath = f.WriteTempFile("server.crt", string(artifacts.Cert)) serverKeyPath = f.WriteTempFile("server.key", string(artifacts.Key)) generator.SetCA(artifacts.CACert, artifacts.CAKey) - generator.Generate("0.0.0.0") + _, err = generator.Generate("0.0.0.0") + framework.ExpectNoError(err) clientCrtPath = f.WriteTempFile("client.crt", string(artifacts.Cert)) clientKeyPath = f.WriteTempFile("client.key", string(artifacts.Key)) }) @@ -139,7 +140,7 @@ var _ = Describe("[Feature: Client-Server]", func() { for _, protocol := range supportProtocols { tmp := protocol - It("one-way authentication: "+tmp, func() { + ginkgo.It("one-way authentication: "+tmp, func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` protocol = %s @@ -155,7 +156,7 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - It("mutual authentication: "+tmp, func() { + ginkgo.It("mutual authentication: "+tmp, func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` protocol = %s @@ -176,13 +177,13 @@ var _ = Describe("[Feature: Client-Server]", func() { } }) - Describe("TLS with custom certificate and specified server name", func() { + ginkgo.Describe("TLS with custom certificate and specified server name", func() { var ( caCrtPath string serverCrtPath, serverKeyPath string clientCrtPath, clientKeyPath string ) - JustBeforeEach(func() { + ginkgo.JustBeforeEach(func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("example.com") framework.ExpectNoError(err) @@ -191,12 +192,13 @@ var _ = Describe("[Feature: Client-Server]", func() { serverCrtPath = f.WriteTempFile("server.crt", string(artifacts.Cert)) serverKeyPath = f.WriteTempFile("server.key", string(artifacts.Key)) generator.SetCA(artifacts.CACert, artifacts.CAKey) - generator.Generate("example.com") + _, err = generator.Generate("example.com") + framework.ExpectNoError(err) clientCrtPath = f.WriteTempFile("client.crt", string(artifacts.Cert)) clientKeyPath = f.WriteTempFile("client.key", string(artifacts.Key)) }) - It("mutual authentication", func() { + ginkgo.It("mutual authentication", func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` tls_cert_file = %s @@ -213,7 +215,7 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - It("mutual authentication with incorrect server name", func() { + ginkgo.It("mutual authentication with incorrect server name", func() { runClientServerTest(f, &generalTestConfigures{ server: fmt.Sprintf(` tls_cert_file = %s @@ -232,7 +234,7 @@ var _ = Describe("[Feature: Client-Server]", func() { }) }) - Describe("TLS with disable_custom_tls_first_byte", func() { + ginkgo.Describe("TLS with disable_custom_tls_first_byte", func() { supportProtocols := []string{"tcp", "kcp", "websocket"} for _, protocol := range supportProtocols { tmp := protocol @@ -250,7 +252,7 @@ var _ = Describe("[Feature: Client-Server]", func() { } }) - Describe("IPv6 bind address", func() { + ginkgo.Describe("IPv6 bind address", func() { supportProtocols := []string{"tcp", "kcp", "websocket"} for _, protocol := range supportProtocols { tmp := protocol diff --git a/test/e2e/basic/cmd.go b/test/e2e/basic/cmd.go index 562310fd..bf8f2467 100644 --- a/test/e2e/basic/cmd.go +++ b/test/e2e/basic/cmd.go @@ -5,21 +5,21 @@ import ( "strconv" "strings" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) const ( ConfigValidStr = "syntax is ok" ) -var _ = Describe("[Feature: Cmd]", func() { +var _ = ginkgo.Describe("[Feature: Cmd]", func() { f := framework.NewDefaultFramework() - Describe("Verify", func() { - It("frps valid", func() { + ginkgo.Describe("Verify", func() { + ginkgo.It("frps valid", func() { path := f.GenerateConfigFile(` [common] bind_addr = 0.0.0.0 @@ -29,7 +29,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.ExpectNoError(err) framework.ExpectTrue(strings.Contains(output, ConfigValidStr), "output: %s", output) }) - It("frps invalid", func() { + ginkgo.It("frps invalid", func() { path := f.GenerateConfigFile(` [common] bind_addr = 0.0.0.0 @@ -39,7 +39,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.ExpectNoError(err) framework.ExpectTrue(!strings.Contains(output, ConfigValidStr), "output: %s", output) }) - It("frpc valid", func() { + ginkgo.It("frpc valid", func() { path := f.GenerateConfigFile(` [common] server_addr = 0.0.0.0 @@ -49,7 +49,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.ExpectNoError(err) framework.ExpectTrue(strings.Contains(output, ConfigValidStr), "output: %s", output) }) - It("frpc invalid", func() { + ginkgo.It("frpc invalid", func() { path := f.GenerateConfigFile(` [common] server_addr = 0.0.0.0 @@ -62,8 +62,8 @@ var _ = Describe("[Feature: Cmd]", func() { }) }) - Describe("Single proxy", func() { - It("TCP", func() { + ginkgo.Describe("Single proxy", func() { + ginkgo.It("TCP", func() { serverPort := f.AllocPort() _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort)) framework.ExpectNoError(err) @@ -77,7 +77,7 @@ var _ = Describe("[Feature: Cmd]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() }) - It("UDP", func() { + ginkgo.It("UDP", func() { serverPort := f.AllocPort() _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort)) framework.ExpectNoError(err) @@ -92,7 +92,7 @@ var _ = Describe("[Feature: Cmd]", func() { Port(remotePort).Ensure() }) - It("HTTP", func() { + ginkgo.It("HTTP", func() { serverPort := f.AllocPort() vhostHTTPPort := f.AllocPort() _, _, err := f.RunFrps("-t", "123", "-p", strconv.Itoa(serverPort), "--vhost_http_port", strconv.Itoa(vhostHTTPPort)) diff --git a/test/e2e/basic/config.go b/test/e2e/basic/config.go index d21bc57c..3ea07b30 100644 --- a/test/e2e/basic/config.go +++ b/test/e2e/basic/config.go @@ -3,18 +3,18 @@ package basic import ( "fmt" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/port" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Config]", func() { +var _ = ginkgo.Describe("[Feature: Config]", func() { f := framework.NewDefaultFramework() - Describe("Template", func() { - It("render by env", func() { + ginkgo.Describe("Template", func() { + ginkgo.It("render by env", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -39,8 +39,8 @@ var _ = Describe("[Feature: Config]", func() { }) }) - Describe("Includes", func() { - It("split tcp proxies into different files", func() { + ginkgo.Describe("Includes", func() { + ginkgo.It("split tcp proxies into different files", func() { serverPort := f.AllocPort() serverConfigPath := f.GenerateConfigFile(fmt.Sprintf(` [common] diff --git a/test/e2e/basic/http.go b/test/e2e/basic/http.go index 8fe73594..0de24abb 100644 --- a/test/e2e/basic/http.go +++ b/test/e2e/basic/http.go @@ -6,16 +6,16 @@ import ( "net/url" "strconv" + "github.com/gorilla/websocket" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/mock/server/httpserver" "github.com/fatedier/frp/test/e2e/pkg/request" - - "github.com/gorilla/websocket" - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: HTTP]", func() { +var _ = ginkgo.Describe("[Feature: HTTP]", func() { f := framework.NewDefaultFramework() getDefaultServerConf := func(vhostHTTPPort int) string { @@ -31,7 +31,7 @@ var _ = Describe("[Feature: HTTP]", func() { ) } - It("HTTP route by locations", func() { + ginkgo.It("HTTP route by locations", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -78,7 +78,7 @@ var _ = Describe("[Feature: HTTP]", func() { } }) - It("HTTP route by HTTP user", func() { + ginkgo.It("HTTP route by HTTP user", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -138,7 +138,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("HTTP Basic Auth", func() { + ginkgo.It("HTTP Basic Auth", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -176,7 +176,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Wildcard domain", func() { + ginkgo.It("Wildcard domain", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -212,7 +212,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Subdomain", func() { + ginkgo.It("Subdomain", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) serverConf += ` @@ -257,7 +257,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Modify headers", func() { + ginkgo.It("Modify headers", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -265,7 +265,7 @@ var _ = Describe("[Feature: HTTP]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(req.Header.Get("X-From-Where"))) + _, _ = w.Write([]byte(req.Header.Get("X-From-Where"))) })), ) f.RunServer("", localServer) @@ -290,7 +290,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Host Header Rewrite", func() { + ginkgo.It("Host Header Rewrite", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) @@ -298,7 +298,7 @@ var _ = Describe("[Feature: HTTP]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(req.Host)) + _, _ = w.Write([]byte(req.Host)) })), ) f.RunServer("", localServer) @@ -322,7 +322,7 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() }) - It("Websocket protocol", func() { + ginkgo.It("Websocket protocol", func() { vhostHTTPPort := f.AllocPort() serverConf := getDefaultServerConf(vhostHTTPPort) diff --git a/test/e2e/basic/server.go b/test/e2e/basic/server.go index 74b421be..a06f6d13 100644 --- a/test/e2e/basic/server.go +++ b/test/e2e/basic/server.go @@ -5,19 +5,19 @@ import ( "net" "strconv" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" clientsdk "github.com/fatedier/frp/test/e2e/pkg/sdk/client" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Server Manager]", func() { +var _ = ginkgo.Describe("[Feature: Server Manager]", func() { f := framework.NewDefaultFramework() - It("Ports Whitelist", func() { + ginkgo.It("Ports Whitelist", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -80,7 +80,7 @@ var _ = Describe("[Feature: Server Manager]", func() { }).ExpectError(true).Ensure() }) - It("Alloc Random Port", func() { + ginkgo.It("Alloc Random Port", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -124,7 +124,7 @@ var _ = Describe("[Feature: Server Manager]", func() { framework.NewRequestExpect(f).Protocol("udp").Port(port).Ensure() }) - It("Port Reuse", func() { + ginkgo.It("Port Reuse", func() { serverConf := consts.DefaultServerConfig // Use same port as PortServer serverConf += fmt.Sprintf(` @@ -145,7 +145,7 @@ var _ = Describe("[Feature: Server Manager]", func() { }).PortName(consts.PortServerName).Ensure() }) - It("healthz", func() { + ginkgo.It("healthz", func() { serverConf := consts.DefaultServerConfig dashboardPort := f.AllocPort() diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index b392954b..6b0d3e01 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -3,12 +3,12 @@ package e2e import ( "testing" - "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/test/e2e/framework" - "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/config" "github.com/onsi/gomega" + + "github.com/fatedier/frp/pkg/util/log" + "github.com/fatedier/frp/test/e2e/framework" ) var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 2dddb952..d1cc6396 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -6,15 +6,14 @@ import ( "os" "testing" - "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/test/e2e/framework" + _ "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/util/log" // test source _ "github.com/fatedier/frp/test/e2e/basic" _ "github.com/fatedier/frp/test/e2e/features" + "github.com/fatedier/frp/test/e2e/framework" _ "github.com/fatedier/frp/test/e2e/plugin" - - _ "github.com/onsi/ginkgo" ) // handleFlags sets up all flags and parses the command line. diff --git a/test/e2e/examples.go b/test/e2e/examples.go index 6423aec1..26eca20b 100644 --- a/test/e2e/examples.go +++ b/test/e2e/examples.go @@ -3,17 +3,17 @@ package e2e import ( "fmt" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Example]", func() { +var _ = ginkgo.Describe("[Feature: Example]", func() { f := framework.NewDefaultFramework() - Describe("TCP", func() { - It("Expose a TCP echo server", func() { + ginkgo.Describe("TCP", func() { + ginkgo.It("Expose a TCP echo server", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig diff --git a/test/e2e/features/bandwidth_limit.go b/test/e2e/features/bandwidth_limit.go index f984fdb9..a912b06a 100644 --- a/test/e2e/features/bandwidth_limit.go +++ b/test/e2e/features/bandwidth_limit.go @@ -5,18 +5,18 @@ import ( "strings" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Bandwidth Limit]", func() { +var _ = ginkgo.Describe("[Feature: Bandwidth Limit]", func() { f := framework.NewDefaultFramework() - It("Proxy Bandwidth Limit", func() { + ginkgo.It("Proxy Bandwidth Limit", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -40,7 +40,7 @@ var _ = Describe("[Feature: Bandwidth Limit]", func() { framework.NewRequestExpect(f).Port(remotePort).RequestModify(func(r *request.Request) { r.Body([]byte(content)).Timeout(30 * time.Second) }).ExpectResp([]byte(content)).Ensure() - duration := time.Now().Sub(start) + duration := time.Since(start) framework.ExpectTrue(duration.Seconds() > 7, "100Kb with 10KB limit, want > 7 seconds, but got %d seconds", duration.Seconds()) }) diff --git a/test/e2e/features/chaos.go b/test/e2e/features/chaos.go index 2049fc77..bae6eb7d 100644 --- a/test/e2e/features/chaos.go +++ b/test/e2e/features/chaos.go @@ -4,15 +4,15 @@ import ( "fmt" "time" - "github.com/fatedier/frp/test/e2e/framework" + "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" ) -var _ = Describe("[Feature: Chaos]", func() { +var _ = ginkgo.Describe("[Feature: Chaos]", func() { f := framework.NewDefaultFramework() - It("reconnect after frps restart", func() { + ginkgo.It("reconnect after frps restart", func() { serverPort := f.AllocPort() serverConfigPath := f.GenerateConfigFile(fmt.Sprintf(` [common] @@ -41,7 +41,7 @@ var _ = Describe("[Feature: Chaos]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() // 2. stop frps, expect request failed - ps.Stop() + _ = ps.Stop() time.Sleep(200 * time.Millisecond) framework.NewRequestExpect(f).Port(remotePort).ExpectError(true).Ensure() @@ -52,7 +52,7 @@ var _ = Describe("[Feature: Chaos]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() // 4. stop frpc, expect request failed - pc.Stop() + _ = pc.Stop() time.Sleep(200 * time.Millisecond) framework.NewRequestExpect(f).Port(remotePort).ExpectError(true).Ensure() diff --git a/test/e2e/features/group.go b/test/e2e/features/group.go index ea6b781f..f66fae05 100644 --- a/test/e2e/features/group.go +++ b/test/e2e/features/group.go @@ -6,16 +6,16 @@ import ( "sync" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/mock/server/httpserver" "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Group]", func() { +var _ = ginkgo.Describe("[Feature: Group]", func() { f := framework.NewDefaultFramework() newHTTPServer := func(port int, respContent string) *httpserver.Server { @@ -60,8 +60,8 @@ var _ = Describe("[Feature: Group]", func() { return results } - Describe("Load Balancing", func() { - It("TCP", func() { + ginkgo.Describe("Load Balancing", func() { + ginkgo.It("TCP", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -112,8 +112,8 @@ var _ = Describe("[Feature: Group]", func() { }) }) - Describe("Health Check", func() { - It("TCP", func() { + ginkgo.Describe("Health Check", func() { + ginkgo.It("TCP", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -178,7 +178,7 @@ var _ = Describe("[Feature: Group]", func() { framework.ExpectContainElements(results, []string{"foo", "bar"}) }) - It("HTTP", func() { + ginkgo.It("HTTP", func() { vhostPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d diff --git a/test/e2e/features/heartbeat.go b/test/e2e/features/heartbeat.go index b0732c37..3ffbd834 100644 --- a/test/e2e/features/heartbeat.go +++ b/test/e2e/features/heartbeat.go @@ -4,15 +4,15 @@ import ( "fmt" "time" - "github.com/fatedier/frp/test/e2e/framework" + "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo" + "github.com/fatedier/frp/test/e2e/framework" ) -var _ = Describe("[Feature: Heartbeat]", func() { +var _ = ginkgo.Describe("[Feature: Heartbeat]", func() { f := framework.NewDefaultFramework() - It("disable application layer heartbeat", func() { + ginkgo.It("disable application layer heartbeat", func() { serverPort := f.AllocPort() serverConf := fmt.Sprintf(` [common] diff --git a/test/e2e/features/monitor.go b/test/e2e/features/monitor.go index d8b656a8..bf074e66 100644 --- a/test/e2e/features/monitor.go +++ b/test/e2e/features/monitor.go @@ -5,18 +5,18 @@ import ( "strings" "time" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Monitor]", func() { +var _ = ginkgo.Describe("[Feature: Monitor]", func() { f := framework.NewDefaultFramework() - It("Prometheus metrics", func() { + ginkgo.It("Prometheus metrics", func() { dashboardPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` enable_prometheus = true diff --git a/test/e2e/features/real_ip.go b/test/e2e/features/real_ip.go index 424d4049..3a2a7e40 100644 --- a/test/e2e/features/real_ip.go +++ b/test/e2e/features/real_ip.go @@ -6,6 +6,9 @@ import ( "net" "net/http" + "github.com/onsi/ginkgo" + pp "github.com/pires/go-proxyproto" + "github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" @@ -13,15 +16,12 @@ import ( "github.com/fatedier/frp/test/e2e/mock/server/streamserver" "github.com/fatedier/frp/test/e2e/pkg/request" "github.com/fatedier/frp/test/e2e/pkg/rpc" - - . "github.com/onsi/ginkgo" - pp "github.com/pires/go-proxyproto" ) -var _ = Describe("[Feature: Real IP]", func() { +var _ = ginkgo.Describe("[Feature: Real IP]", func() { f := framework.NewDefaultFramework() - It("HTTP X-Forwarded-For", func() { + ginkgo.It("HTTP X-Forwarded-For", func() { vhostHTTPPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d @@ -31,7 +31,7 @@ var _ = Describe("[Feature: Real IP]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(req.Header.Get("X-Forwarded-For"))) + _, _ = w.Write([]byte(req.Header.Get("X-Forwarded-For"))) })), ) f.RunServer("", localServer) @@ -52,11 +52,10 @@ var _ = Describe("[Feature: Real IP]", func() { }). ExpectResp([]byte("127.0.0.1")). Ensure() - }) - Describe("Proxy Protocol", func() { - It("TCP", func() { + ginkgo.Describe("Proxy Protocol", func() { + ginkgo.It("TCP", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -77,7 +76,7 @@ var _ = Describe("[Feature: Real IP]", func() { } buf := []byte(ppHeader.SourceAddr.String()) - rpc.WriteBytes(c, buf) + _, _ = rpc.WriteBytes(c, buf) } })) f.RunServer("", localServer) @@ -106,7 +105,7 @@ var _ = Describe("[Feature: Real IP]", func() { }) }) - It("HTTP", func() { + ginkgo.It("HTTP", func() { vhostHTTPPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d diff --git a/test/e2e/framework/cleanup.go b/test/e2e/framework/cleanup.go index d2d1c5a6..15e1a9dd 100644 --- a/test/e2e/framework/cleanup.go +++ b/test/e2e/framework/cleanup.go @@ -6,13 +6,16 @@ import ( // CleanupActionHandle is an integer pointer type for handling cleanup action type CleanupActionHandle *int + type cleanupFuncHandle struct { actionHandle CleanupActionHandle actionHook func() } -var cleanupActionsLock sync.Mutex -var cleanupHookList = []cleanupFuncHandle{} +var ( + cleanupActionsLock sync.Mutex + cleanupHookList = []cleanupFuncHandle{} +) // AddCleanupAction installs a function that will be called in the event of the // whole test being terminated. This allows arbitrary pieces of the overall diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index 344f64c3..c22c6af7 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -9,12 +9,12 @@ import ( "strings" "text/template" + "github.com/onsi/ginkgo" + "github.com/onsi/ginkgo/config" + "github.com/fatedier/frp/test/e2e/mock/server" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/process" - - "github.com/onsi/ginkgo" - "github.com/onsi/ginkgo/config" ) type Options struct { @@ -102,7 +102,8 @@ func (f *Framework) BeforeEach() { for k, v := range params { switch t := v.(type) { case int: - f.usedPorts[k] = int(t) + f.usedPorts[k] = t + default: } } } @@ -116,14 +117,14 @@ func (f *Framework) AfterEach() { // stop processor for _, p := range f.serverProcesses { - p.Stop() + _ = p.Stop() if TestContext.Debug { fmt.Println(p.ErrorOutput()) fmt.Println(p.StdOutput()) } } for _, p := range f.clientProcesses { - p.Stop() + _ = p.Stop() if TestContext.Debug { fmt.Println(p.ErrorOutput()) fmt.Println(p.StdOutput()) @@ -259,7 +260,7 @@ func (f *Framework) SetEnvs(envs []string) { func (f *Framework) WriteTempFile(name string, content string) string { filePath := filepath.Join(f.TempDirectory, name) - err := os.WriteFile(filePath, []byte(content), 0766) + err := os.WriteFile(filePath, []byte(content), 0o766) ExpectNoError(err) return filePath } diff --git a/test/e2e/framework/log.go b/test/e2e/framework/log.go index ff33f41d..b72b3772 100644 --- a/test/e2e/framework/log.go +++ b/test/e2e/framework/log.go @@ -58,11 +58,12 @@ var codeFilterRE = regexp.MustCompile(`/github.com/onsi/ginkgo/`) // From the remaining entries it automatically filters out useless ones like // entries coming from Ginkgo. // -// This is a modified copy of PruneStack in https://github.com/onsi/ginkgo/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25: -// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter) -// - source code filtering updated to be specific to Kubernetes -// - optimized to use bytes and in-place slice filtering from -// https://github.com/golang/go/wiki/SliceTricks#filter-in-place +// This is a modified copy of PruneStack in +// https://github.com/onsi/ginkgo/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25: +// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter) +// - source code filtering updated to be specific to Kubernetes +// - optimized to use bytes and in-place slice filtering from +// https://github.com/golang/go/wiki/SliceTricks#filter-in-place func PrunedStack(skip int) []byte { fullStackTrace := debug.Stack() stack := bytes.Split(fullStackTrace, []byte("\n")) @@ -82,7 +83,7 @@ func PrunedStack(skip int) []byte { n := 0 for i := 0; i < len(stack)/2; i++ { // We filter out based on the source code file name. - if !codeFilterRE.Match([]byte(stack[i*2+1])) { + if !codeFilterRE.Match(stack[i*2+1]) { stack[n] = stack[i*2] stack[n+1] = stack[i*2+1] n += 2 diff --git a/test/e2e/framework/mockservers.go b/test/e2e/framework/mockservers.go index af41ab90..32f7ac38 100644 --- a/test/e2e/framework/mockservers.go +++ b/test/e2e/framework/mockservers.go @@ -33,9 +33,11 @@ func NewMockServers(portAllocator *port.Allocator) *MockServers { httpPort := portAllocator.Get() s.tcpEchoServer = streamserver.New(streamserver.TCP, streamserver.WithBindPort(tcpPort)) s.udpEchoServer = streamserver.New(streamserver.UDP, streamserver.WithBindPort(udpPort)) - s.httpSimpleServer = httpserver.New(httpserver.WithBindPort(httpPort), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - w.Write([]byte(consts.TestString)) - }))) + s.httpSimpleServer = httpserver.New(httpserver.WithBindPort(httpPort), + httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + _, _ = w.Write([]byte(consts.TestString)) + })), + ) udsIndex := portAllocator.Get() udsAddr := fmt.Sprintf("%s/frp_echo_server_%d.sock", os.TempDir(), udsIndex) diff --git a/test/e2e/framework/process.go b/test/e2e/framework/process.go index 32ef2f84..7b9b238e 100644 --- a/test/e2e/framework/process.go +++ b/test/e2e/framework/process.go @@ -14,12 +14,8 @@ import ( // The first template should always be frps. func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []string) ([]*process.Process, []*process.Process) { templates := make([]string, 0, len(serverTemplates)+len(clientTemplates)) - for _, t := range serverTemplates { - templates = append(templates, t) - } - for _, t := range clientTemplates { - templates = append(templates, t) - } + templates = append(templates, serverTemplates...) + templates = append(templates, clientTemplates...) outs, ports, err := f.RenderTemplates(templates) ExpectNoError(err) ExpectTrue(len(templates) > 0) @@ -31,7 +27,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str currentServerProcesses := make([]*process.Process, 0, len(serverTemplates)) for i := range serverTemplates { path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-server-%d", i)) - err = os.WriteFile(path, []byte(outs[i]), 0666) + err = os.WriteFile(path, []byte(outs[i]), 0o666) ExpectNoError(err) flog.Trace("[%s] %s", path, outs[i]) @@ -48,7 +44,7 @@ func (f *Framework) RunProcesses(serverTemplates []string, clientTemplates []str for i := range clientTemplates { index := i + len(serverTemplates) path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-client-%d", i)) - err = os.WriteFile(path, []byte(outs[index]), 0666) + err = os.WriteFile(path, []byte(outs[index]), 0o666) ExpectNoError(err) flog.Trace("[%s] %s", path, outs[index]) @@ -91,7 +87,7 @@ func (f *Framework) RunFrpc(args ...string) (*process.Process, string, error) { func (f *Framework) GenerateConfigFile(content string) string { f.configFileIndex++ path := filepath.Join(f.TempDirectory, fmt.Sprintf("frp-e2e-config-%d", f.configFileIndex)) - err := os.WriteFile(path, []byte(content), 0666) + err := os.WriteFile(path, []byte(content), 0o666) ExpectNoError(err) return path } diff --git a/test/e2e/framework/request.go b/test/e2e/framework/request.go index 5dccd661..6b75a259 100644 --- a/test/e2e/framework/request.go +++ b/test/e2e/framework/request.go @@ -11,7 +11,7 @@ import ( func SpecifiedHTTPBodyHandler(body []byte) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { - w.Write(body) + _, _ = w.Write(body) } } diff --git a/test/e2e/framework/test_context.go b/test/e2e/framework/test_context.go index 958c78f8..42a66445 100644 --- a/test/e2e/framework/test_context.go +++ b/test/e2e/framework/test_context.go @@ -24,7 +24,6 @@ var TestContext TestContextType // The other Register*Flags methods below can be used to add more // test-specific flags. However, those settings then get added // regardless whether the test is actually in the test suite. -// func RegisterCommonFlags(flags *flag.FlagSet) { // Turn on EmitSpecProgress to get spec progress (especially on interrupt) config.GinkgoConfig.EmitSpecProgress = true diff --git a/test/e2e/mock/server/httpserver/server.go b/test/e2e/mock/server/httpserver/server.go index a811ac27..f9818a0d 100644 --- a/test/e2e/mock/server/httpserver/server.go +++ b/test/e2e/mock/server/httpserver/server.go @@ -5,6 +5,7 @@ import ( "net" "net/http" "strconv" + "time" ) type Server struct { @@ -44,7 +45,7 @@ func WithBindPort(port int) Option { } } -func WithTlsConfig(tlsConfig *tls.Config) Option { +func WithTLSConfig(tlsConfig *tls.Config) Option { return func(s *Server) *Server { s.tlsConfig = tlsConfig return s @@ -61,7 +62,7 @@ func WithHandler(h http.Handler) Option { func WithResponse(resp []byte) Option { return func(s *Server) *Server { s.handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write(resp) + _, _ = w.Write(resp) }) return s } @@ -74,16 +75,21 @@ func (s *Server) Run() error { addr := net.JoinHostPort(s.bindAddr, strconv.Itoa(s.bindPort)) hs := &http.Server{ - Addr: addr, - Handler: s.handler, - TLSConfig: s.tlsConfig, + Addr: addr, + Handler: s.handler, + TLSConfig: s.tlsConfig, + ReadHeaderTimeout: time.Minute, } s.hs = hs if s.tlsConfig == nil { - go hs.Serve(s.l) + go func() { + _ = hs.Serve(s.l) + }() } else { - go hs.ServeTLS(s.l, "", "") + go func() { + _ = hs.ServeTLS(s.l, "", "") + }() } return nil } diff --git a/test/e2e/mock/server/streamserver/server.go b/test/e2e/mock/server/streamserver/server.go index 1dde353a..9e237d96 100644 --- a/test/e2e/mock/server/streamserver/server.go +++ b/test/e2e/mock/server/streamserver/server.go @@ -127,7 +127,7 @@ func (s *Server) handle(c net.Conn) { if len(s.respContent) > 0 { buf = s.respContent } - rpc.WriteBytes(c, buf) + _, _ = rpc.WriteBytes(c, buf) } } diff --git a/test/e2e/pkg/cert/generator.go b/test/e2e/pkg/cert/generator.go index 5c11b226..fb22522b 100644 --- a/test/e2e/pkg/cert/generator.go +++ b/test/e2e/pkg/cert/generator.go @@ -22,8 +22,8 @@ type Artifacts struct { ResourceVersion string } -// CertGenerator is an interface to provision the serving certificate. -type CertGenerator interface { +// Generator is an interface to provision the serving certificate. +type Generator interface { // Generate returns a Artifacts struct. Generate(CommonName string) (*Artifacts, error) // SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert. diff --git a/test/e2e/pkg/cert/selfsigned.go b/test/e2e/pkg/cert/selfsigned.go index 4f9ed573..82762d09 100644 --- a/test/e2e/pkg/cert/selfsigned.go +++ b/test/e2e/pkg/cert/selfsigned.go @@ -23,7 +23,7 @@ type SelfSignedCertGenerator struct { caCert []byte } -var _ CertGenerator = &SelfSignedCertGenerator{} +var _ Generator = &SelfSignedCertGenerator{} // SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert. func (cp *SelfSignedCertGenerator) SetCA(caKey, caCert []byte) { diff --git a/test/e2e/pkg/port/util.go b/test/e2e/pkg/port/util.go index 9cf1204f..073bf3c7 100644 --- a/test/e2e/pkg/port/util.go +++ b/test/e2e/pkg/port/util.go @@ -26,16 +26,17 @@ func unmarshalFromName(name string) (*nameBuilder, error) { builder.name = arrs[1] case 4: builder.name = arrs[1] - if fromPort, err := strconv.Atoi(arrs[2]); err != nil { + fromPort, err := strconv.Atoi(arrs[2]) + if err != nil { return nil, fmt.Errorf("error range port from") - } else { - builder.rangePortFrom = fromPort } - if toPort, err := strconv.Atoi(arrs[3]); err != nil { + builder.rangePortFrom = fromPort + + toPort, err := strconv.Atoi(arrs[3]) + if err != nil { return nil, fmt.Errorf("error range port to") - } else { - builder.rangePortTo = toPort } + builder.rangePortTo = toPort default: return nil, fmt.Errorf("error port name format") } diff --git a/test/e2e/pkg/request/request.go b/test/e2e/pkg/request/request.go index cf6352f3..96e714f9 100644 --- a/test/e2e/pkg/request/request.go +++ b/test/e2e/pkg/request/request.go @@ -12,9 +12,10 @@ import ( "strconv" "time" + libdial "github.com/fatedier/golib/net/dial" + "github.com/fatedier/frp/test/e2e/pkg/rpc" "github.com/fatedier/frp/test/e2e/pkg/utils" - libdial "github.com/fatedier/golib/net/dial" ) type Request struct { @@ -181,7 +182,7 @@ func (r *Request) Do() (*Response, error) { defer conn.Close() if r.timeout > 0 { - conn.SetDeadline(time.Now().Add(r.timeout)) + _ = conn.SetDeadline(time.Now().Add(r.timeout)) } buf, err := r.sendRequestByConn(conn, r.body) if err != nil { @@ -199,7 +200,6 @@ type Response struct { func (r *Request) sendHTTPRequest(method, urlstr string, host string, headers map[string]string, proxy string, body []byte, tlsConfig *tls.Config, ) (*Response, error) { - var inBody io.Reader if len(body) != 0 { inBody = bytes.NewReader(body) @@ -240,6 +240,7 @@ func (r *Request) sendHTTPRequest(method, urlstr string, host string, headers ma if err != nil { return nil, err } + defer resp.Body.Close() ret := &Response{Code: resp.StatusCode, Header: resp.Header} buf, err := io.ReadAll(resp.Body) diff --git a/test/e2e/pkg/rpc/rpc.go b/test/e2e/pkg/rpc/rpc.go index ee3aef56..d6026449 100644 --- a/test/e2e/pkg/rpc/rpc.go +++ b/test/e2e/pkg/rpc/rpc.go @@ -9,7 +9,10 @@ import ( func WriteBytes(w io.Writer, buf []byte) (int, error) { out := bytes.NewBuffer(nil) - binary.Write(out, binary.BigEndian, int64(len(buf))) + if err := binary.Write(out, binary.BigEndian, int64(len(buf))); err != nil { + return 0, err + } + out.Write(buf) return w.Write(out.Bytes()) } diff --git a/test/e2e/plugin/client.go b/test/e2e/plugin/client.go index afbd0a2c..081c88ff 100644 --- a/test/e2e/plugin/client.go +++ b/test/e2e/plugin/client.go @@ -5,6 +5,8 @@ import ( "fmt" "strconv" + "github.com/onsi/ginkgo" + "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" @@ -12,15 +14,13 @@ import ( "github.com/fatedier/frp/test/e2e/pkg/cert" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Client-Plugins]", func() { +var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { f := framework.NewDefaultFramework() - Describe("UnixDomainSocket", func() { - It("Expose a unix domain socket echo server", func() { + ginkgo.Describe("UnixDomainSocket", func() { + ginkgo.It("Expose a unix domain socket echo server", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -76,7 +76,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { }) }) - It("http_proxy", func() { + ginkgo.It("http_proxy", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -108,7 +108,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { }) }) - It("socks5 proxy", func() { + ginkgo.It("socks5 proxy", func() { serverConf := consts.DefaultServerConfig clientConf := consts.DefaultClientConfig @@ -135,7 +135,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { }).Ensure() }) - It("static_file", func() { + ginkgo.It("static_file", func() { vhostPort := f.AllocPort() serverConf := consts.DefaultServerConfig + fmt.Sprintf(` vhost_http_port = %d @@ -184,7 +184,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { ).ExpectResp([]byte("foo")).Ensure() }) - It("http2https", func() { + ginkgo.It("http2https", func() { serverConf := consts.DefaultServerConfig vhostHTTPPort := f.AllocPort() serverConf += fmt.Sprintf(` @@ -206,7 +206,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { framework.ExpectNoError(err) localServer := httpserver.New( httpserver.WithBindPort(localPort), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), httpserver.WithResponse([]byte("test")), ) f.RunServer("", localServer) @@ -220,7 +220,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { Ensure() }) - It("https2http", func() { + ginkgo.It("https2http", func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("example.com") framework.ExpectNoError(err) @@ -264,7 +264,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { Ensure() }) - It("https2https", func() { + ginkgo.It("https2https", func() { generator := &cert.SelfSignedCertGenerator{} artifacts, err := generator.Generate("example.com") framework.ExpectNoError(err) @@ -295,7 +295,7 @@ var _ = Describe("[Feature: Client-Plugins]", func() { localServer := httpserver.New( httpserver.WithBindPort(localPort), httpserver.WithResponse([]byte("test")), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), ) f.RunServer("", localServer) diff --git a/test/e2e/plugin/server.go b/test/e2e/plugin/server.go index 2af1eba8..e4619573 100644 --- a/test/e2e/plugin/server.go +++ b/test/e2e/plugin/server.go @@ -4,25 +4,25 @@ import ( "fmt" "time" + "github.com/onsi/ginkgo" + plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" "github.com/fatedier/frp/test/e2e/framework/consts" - - . "github.com/onsi/ginkgo" ) -var _ = Describe("[Feature: Server-Plugins]", func() { +var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() { f := framework.NewDefaultFramework() - Describe("Login", func() { + ginkgo.Describe("Login", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.LoginContent{} return &r } - It("Auth for custom meta token", func() { + ginkgo.It("Auth for custom meta token", func() { localPort := f.AllocPort() clientAddressGot := false @@ -79,14 +79,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("NewProxy", func() { + ginkgo.Describe("NewProxy", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewProxyContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() handler := func(req *plugin.Request) *plugin.Response { var ret plugin.Response @@ -123,7 +123,7 @@ var _ = Describe("[Feature: Server-Plugins]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() }) - It("Mofify RemotePort", func() { + ginkgo.It("Mofify RemotePort", func() { localPort := f.AllocPort() remotePort := f.AllocPort() handler := func(req *plugin.Request) *plugin.Response { @@ -158,14 +158,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("CloseProxy", func() { + ginkgo.Describe("CloseProxy", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.CloseProxyContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var recordProxyName string handler := func(req *plugin.Request) *plugin.Response { @@ -199,7 +199,7 @@ var _ = Describe("[Feature: Server-Plugins]", func() { framework.NewRequestExpect(f).Port(remotePort).Ensure() for _, c := range clients { - c.Stop() + _ = c.Stop() } time.Sleep(1 * time.Second) @@ -208,14 +208,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("Ping", func() { + ginkgo.Describe("Ping", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.PingContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var record string @@ -258,14 +258,14 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("NewWorkConn", func() { + ginkgo.Describe("NewWorkConn", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewWorkConnContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var record string @@ -304,13 +304,13 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("NewUserConn", func() { + ginkgo.Describe("NewUserConn", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewUserConnContent{} return &r } - It("Validate Info", func() { + ginkgo.It("Validate Info", func() { localPort := f.AllocPort() var record string @@ -349,13 +349,13 @@ var _ = Describe("[Feature: Server-Plugins]", func() { }) }) - Describe("HTTPS Protocol", func() { + ginkgo.Describe("HTTPS Protocol", func() { newFunc := func() *plugin.Request { var r plugin.Request r.Content = &plugin.NewUserConnContent{} return &r } - It("Validate Login Info, disable tls verify", func() { + ginkgo.It("Validate Login Info, disable tls verify", func() { localPort := f.AllocPort() var record string diff --git a/test/e2e/plugin/utils.go b/test/e2e/plugin/utils.go index c0d7db3d..51de01d9 100644 --- a/test/e2e/plugin/utils.go +++ b/test/e2e/plugin/utils.go @@ -11,14 +11,14 @@ import ( "github.com/fatedier/frp/test/e2e/mock/server/httpserver" ) -type PluginHandler func(req *plugin.Request) *plugin.Response +type Handler func(req *plugin.Request) *plugin.Response type NewPluginRequest func() *plugin.Request -func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler PluginHandler, tlsConfig *tls.Config) *httpserver.Server { +func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler Handler, tlsConfig *tls.Config) *httpserver.Server { return httpserver.New( httpserver.WithBindPort(port), - httpserver.WithTlsConfig(tlsConfig), + httpserver.WithTLSConfig(tlsConfig), httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { r := newFunc() buf, err := io.ReadAll(req.Body) @@ -35,7 +35,7 @@ func NewHTTPPluginServer(port int, newFunc NewPluginRequest, handler PluginHandl resp := handler(r) buf, _ = json.Marshal(resp) log.Trace("plugin response: %s", string(buf)) - w.Write(buf) + _, _ = w.Write(buf) })), ) }