From 75383a95b360d3ed05b946800c627488e6a1fefc Mon Sep 17 00:00:00 2001 From: Jiajun Huang Date: Thu, 30 May 2019 12:11:59 +0800 Subject: [PATCH 1/5] resp.Body must be closed after function return whether it's success or fail, otherwise it will cause memory leak ref: https://golang.org/pkg/net/http/ --- cmd/frpc/sub/reload.go | 21 ++++--- cmd/frpc/sub/status.go | 127 +++++++++++++++++++++-------------------- tests/util/util.go | 88 ++++++++++++++-------------- 3 files changed, 118 insertions(+), 118 deletions(-) diff --git a/cmd/frpc/sub/reload.go b/cmd/frpc/sub/reload.go index 647bf1e2..46118c3e 100644 --- a/cmd/frpc/sub/reload.go +++ b/cmd/frpc/sub/reload.go @@ -76,17 +76,16 @@ func reload() error { resp, err := http.DefaultClient.Do(req) if err != nil { return err - } else { - if resp.StatusCode == 200 { - return nil - } + } + defer resp.Body.Close() - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) + if resp.StatusCode == 200 { + return nil + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err } - return nil + return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) } diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go index 883c7a7f..91887ef1 100644 --- a/cmd/frpc/sub/status.go +++ b/cmd/frpc/sub/status.go @@ -78,76 +78,77 @@ func status() error { resp, err := http.DefaultClient.Do(req) if err != nil { return err - } else { - if resp.StatusCode != 200 { - return fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - res := &client.StatusResp{} - err = json.Unmarshal(body, &res) - if err != nil { - return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) - } + } + if resp.StatusCode != 200 { + return fmt.Errorf("admin api status code [%d]", resp.StatusCode) + } + defer resp.Body.Close() - fmt.Println("Proxy Status...") - if len(res.Tcp) > 0 { - fmt.Printf("TCP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Tcp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + res := &client.StatusResp{} + err = json.Unmarshal(body, &res) + if err != nil { + return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) + } + + fmt.Println("Proxy Status...") + if len(res.Tcp) > 0 { + fmt.Printf("TCP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Tcp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) } - if len(res.Udp) > 0 { - fmt.Printf("UDP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Udp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") + tbl.Print() + fmt.Println("") + } + if len(res.Udp) > 0 { + fmt.Printf("UDP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Udp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) } - if len(res.Http) > 0 { - fmt.Printf("HTTP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Http { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") + tbl.Print() + fmt.Println("") + } + if len(res.Http) > 0 { + fmt.Printf("HTTP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Http { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) } - if len(res.Https) > 0 { - fmt.Printf("HTTPS") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Https { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") + tbl.Print() + fmt.Println("") + } + if len(res.Https) > 0 { + fmt.Printf("HTTPS") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Https { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) } - if len(res.Stcp) > 0 { - fmt.Printf("STCP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Stcp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") + tbl.Print() + fmt.Println("") + } + if len(res.Stcp) > 0 { + fmt.Printf("STCP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Stcp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) } - if len(res.Xtcp) > 0 { - fmt.Printf("XTCP") - tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") - for _, ps := range res.Xtcp { - tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) - } - tbl.Print() - fmt.Println("") + tbl.Print() + fmt.Println("") + } + if len(res.Xtcp) > 0 { + fmt.Printf("XTCP") + tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error") + for _, ps := range res.Xtcp { + tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err) } + tbl.Print() + fmt.Println("") } + return nil } diff --git a/tests/util/util.go b/tests/util/util.go index 2070ce31..f4e40111 100644 --- a/tests/util/util.go +++ b/tests/util/util.go @@ -28,51 +28,51 @@ func GetProxyStatus(statusAddr string, user string, passwd string, name string) resp, err := http.DefaultClient.Do(req) if err != nil { return status, err - } else { - if resp.StatusCode != 200 { - return status, fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return status, err - } - allStatus := &client.StatusResp{} - err = json.Unmarshal(body, &allStatus) - if err != nil { - return status, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) - } - for _, s := range allStatus.Tcp { - if s.Name == name { - return &s, nil - } + } + if resp.StatusCode != 200 { + return status, fmt.Errorf("admin api status code [%d]", resp.StatusCode) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return status, err + } + allStatus := &client.StatusResp{} + err = json.Unmarshal(body, &allStatus) + if err != nil { + return status, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body))) + } + for _, s := range allStatus.Tcp { + if s.Name == name { + return &s, nil } - for _, s := range allStatus.Udp { - if s.Name == name { - return &s, nil - } + } + for _, s := range allStatus.Udp { + if s.Name == name { + return &s, nil } - for _, s := range allStatus.Http { - if s.Name == name { - return &s, nil - } + } + for _, s := range allStatus.Http { + if s.Name == name { + return &s, nil } - for _, s := range allStatus.Https { - if s.Name == name { - return &s, nil - } + } + for _, s := range allStatus.Https { + if s.Name == name { + return &s, nil } - for _, s := range allStatus.Stcp { - if s.Name == name { - return &s, nil - } + } + for _, s := range allStatus.Stcp { + if s.Name == name { + return &s, nil } - for _, s := range allStatus.Xtcp { - if s.Name == name { - return &s, nil - } + } + for _, s := range allStatus.Xtcp { + if s.Name == name { + return &s, nil } } + return status, errors.New("no proxy status found") } @@ -87,13 +87,13 @@ func ReloadConf(reloadAddr string, user string, passwd string) error { resp, err := http.DefaultClient.Do(req) if err != nil { return err - } else { - if resp.StatusCode != 200 { - return fmt.Errorf("admin api status code [%d]", resp.StatusCode) - } - defer resp.Body.Close() - io.Copy(ioutil.Discard, resp.Body) } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("admin api status code [%d]", resp.StatusCode) + } + io.Copy(ioutil.Discard, resp.Body) return nil } From 2d24879fa37388e44b48955bff9ace25c9ec8bc6 Mon Sep 17 00:00:00 2001 From: Jiajun Huang Date: Fri, 31 May 2019 15:56:05 +0800 Subject: [PATCH 2/5] fix --- cmd/frpc/sub/status.go | 3 ++- go.sum | 15 +++++++++++++++ tests/util/util.go | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go index 91887ef1..8f55ce13 100644 --- a/cmd/frpc/sub/status.go +++ b/cmd/frpc/sub/status.go @@ -79,10 +79,11 @@ func status() error { if err != nil { return err } + defer resp.Body.Close() + if resp.StatusCode != 200 { return fmt.Errorf("admin api status code [%d]", resp.StatusCode) } - defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { diff --git a/go.sum b/go.sum index 64df3822..9535e3c0 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,17 @@ +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw= github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk= github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049 h1:teH578mf2ii42NHhIp3PhgvjU5bv+NFMq9fSQR8NaG8= github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049/go.mod h1:DqIrnl0rp3Zybg9zbJmozTy1n8fYJoX+QoAj9slIkKM= github.com/fatedier/kcp-go v2.0.4-0.20190317085623-2063a803e6fe+incompatible h1:pNNeBKz1jtMDupiwvtEGFTujA3J86xoEXGSkwVeYFsw= github.com/fatedier/kcp-go v2.0.4-0.20190317085623-2063a803e6fe+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= @@ -22,16 +26,27 @@ github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc h1:lNOt1SMsgHXTdpuGw+RpnJtzUcCb/oRKZP65pBy9pr8= github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc/go.mod h1:6/gX3+E/IYGa0wMORlSMla999awQFdbaeQCHjSMKIzY= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rakyll/statik v0.1.1 h1:fCLHsIMajHqD5RKigbFXpvX3dN7c80Pm12+NCrI3kvg= github.com/rakyll/statik v0.1.1/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= +github.com/rodaine/table v1.0.0 h1:UaCJG5Axc/cNXVGXqnCrffm1KxP0OfYLe1HuJLf5sFY= github.com/rodaine/table v1.0.0/go.mod h1:YAUzwPOji0DUJNEvggdxyQcUAl4g3hDRcFlyjnnR51I= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047 h1:K+jtWCOuZgCra7eXZ/VWn2FbJmrA/D058mTXhh2rq+8= github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= +github.com/templexxx/xor v0.0.0-20170926022130-0af8e873c554 h1:pexgSe+JCFuxG+uoMZLO+ce8KHtdHGhst4cs6rw3gmk= github.com/templexxx/xor v0.0.0-20170926022130-0af8e873c554/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= +github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8 h1:6CNSDqI1wiE+JqyOy5Qt/yo/DoNI2/QmmOZeiCid2Nw= github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= +github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks= github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw= +golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab h1:w4c/LoOA2vE8SYwh8wEEQVRUwpph7TtcjH7AtZvOjy0= golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180524181706-dfa909b99c79 h1:1FDlG4HI84rVePw1/0E/crL5tt2N+1blLJpY6UZ6krs= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/tests/util/util.go b/tests/util/util.go index f4e40111..4a4e6ffc 100644 --- a/tests/util/util.go +++ b/tests/util/util.go @@ -29,10 +29,10 @@ func GetProxyStatus(statusAddr string, user string, passwd string, name string) if err != nil { return status, err } + defer resp.Body.Close() if resp.StatusCode != 200 { return status, fmt.Errorf("admin api status code [%d]", resp.StatusCode) } - defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return status, err From 802d1c1861527f7c9c06b76c47d17fea38a5a16b Mon Sep 17 00:00:00 2001 From: zhangwei <26432832+Arugal@users.noreply.github.com> Date: Sat, 1 Jun 2019 10:09:13 +0800 Subject: [PATCH 3/5] replace the _ --- cmd/frps/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/frps/root.go b/cmd/frps/root.go index e8def792..4dcd8896 100644 --- a/cmd/frps/root.go +++ b/cmd/frps/root.go @@ -79,7 +79,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password") rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file") rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level") - rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log_max_days") + rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log max days") rootCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token") rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host") rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports") From 17cc0735d1bce68ebe73a26c24475c1a854dd334 Mon Sep 17 00:00:00 2001 From: fatedier Date: Fri, 12 Jul 2019 16:53:21 +0800 Subject: [PATCH 4/5] add read timeout for TLS check operation --- server/service.go | 11 ++++++++++- utils/net/tls.go | 14 +++++++++++--- utils/version/version.go | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/server/service.go b/server/service.go index 6cd8e502..d1207f44 100644 --- a/server/service.go +++ b/server/service.go @@ -259,7 +259,16 @@ func (svr *Service) HandleListener(l frpNet.Listener) { log.Warn("Listener for incoming connections from client closed") return } - c = frpNet.CheckAndEnableTLSServerConn(c, svr.tlsConfig) + + log.Trace("start check TLS connection...") + originConn := c + c, err = frpNet.CheckAndEnableTLSServerConnWithTimeout(c, svr.tlsConfig, connReadTimeout) + if err != nil { + log.Warn("CheckAndEnableTLSServerConnWithTimeout error: %v", err) + originConn.Close() + continue + } + log.Trace("success check TLS connection") // Start a new goroutine for dealing connections. go func(frpConn frpNet.Conn) { diff --git a/utils/net/tls.go b/utils/net/tls.go index ae1bfc70..4ac51d5f 100644 --- a/utils/net/tls.go +++ b/utils/net/tls.go @@ -17,6 +17,7 @@ package net import ( "crypto/tls" "net" + "time" gnet "github.com/fatedier/golib/net" ) @@ -31,10 +32,17 @@ func WrapTLSClientConn(c net.Conn, tlsConfig *tls.Config) (out Conn) { return } -func CheckAndEnableTLSServerConn(c net.Conn, tlsConfig *tls.Config) (out Conn) { - sc, r := gnet.NewSharedConnSize(c, 1) +func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, timeout time.Duration) (out Conn, err error) { + sc, r := gnet.NewSharedConnSize(c, 2) buf := make([]byte, 1) - n, _ := r.Read(buf) + var n int + c.SetReadDeadline(time.Now().Add(timeout)) + n, err = r.Read(buf) + c.SetReadDeadline(time.Time{}) + if err != nil { + return + } + if n == 1 && int(buf[0]) == FRP_TLS_HEAD_BYTE { out = WrapConn(tls.Server(c, tlsConfig)) } else { diff --git a/utils/version/version.go b/utils/version/version.go index 9bc4934d..da23fbea 100644 --- a/utils/version/version.go +++ b/utils/version/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -var version string = "0.27.0" +var version string = "0.27.1" func Full() string { return version From 541ad8d899229c363ebb6d55c44d231cf8cc7f7b Mon Sep 17 00:00:00 2001 From: fatedier Date: Fri, 12 Jul 2019 17:59:45 +0800 Subject: [PATCH 5/5] update ISSUE_TEMPLATE --- .github/ISSUE_TEMPLATE | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index 858c31ad..f9f7faec 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -1,5 +1,7 @@ Issue is only used for submiting bug report and documents typo. If there are same issues or answers can be found in documents, we will close it directly. (为了节约时间,提高处理问题的效率,不按照格式填写的 issue 将会直接关闭。) +(请不要在 issue 评论中出现无意义的 **加1**,**我也是** 等内容,将会被直接删除。) +(由于个人精力有限,和系统环境,网络环境等相关的求助问题请转至其他论坛或社交平台。) Use the commands below to provide key information from your environment: You do NOT have to include this information if this is a FEATURE REQUEST