From 75383a95b360d3ed05b946800c627488e6a1fefc Mon Sep 17 00:00:00 2001 From: Jiajun Huang Date: Thu, 30 May 2019 12:11:59 +0800 Subject: [PATCH 1/2] 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 | 23 ++++--- cmd/frpc/sub/status.go | 141 +++++++++++++++++++++-------------------- tests/util/util.go | 98 ++++++++++++++-------------- 3 files changed, 131 insertions(+), 131 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() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - return fmt.Errorf("code [%d], %s", resp.StatusCode, strings.TrimSpace(string(body))) } - return nil + defer resp.Body.Close() + + if resp.StatusCode == 200 { + return nil + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + 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))) - } - - 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("") - } - 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("") - } - 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("") - } - 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("") - } - 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("") - } - 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("") - } } + 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))) + } + + 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("") + } + 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("") + } + 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("") + } + 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("") + } + 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("") + } + 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 - } - } - 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.Https { - 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 - } + } + 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.Http { + 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.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/2] 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