Fix memory leaks due to not closing http request body (#997)
This commit is contained in:
parent
4828d197d6
commit
62052e0159
5 changed files with 32 additions and 28 deletions
|
|
@ -181,8 +181,9 @@ func (evse *EVSEWifi) Enabled() (bool, error) {
|
|||
return params.EvseState, err
|
||||
}
|
||||
|
||||
// checkError checks for EVSE error response with HTTP 200 status
|
||||
func (evse *EVSEWifi) checkError(b []byte, err error) error {
|
||||
// get executes GET request and checks for EVSE error response
|
||||
func (evse *EVSEWifi) get(uri string) error {
|
||||
b, err := evse.GetBody(uri)
|
||||
if err == nil && !strings.HasPrefix(string(b), evseSuccess) {
|
||||
err = errors.New(string(b))
|
||||
}
|
||||
|
|
@ -200,14 +201,14 @@ func (evse *EVSEWifi) Enable(enable bool) error {
|
|||
}
|
||||
url = fmt.Sprintf("%s?current=%d", evse.apiURL(evseSetCurrent), current)
|
||||
}
|
||||
return evse.checkError(evse.GetBody(url))
|
||||
return evse.get(url)
|
||||
}
|
||||
|
||||
// MaxCurrent implements the api.Charger interface
|
||||
func (evse *EVSEWifi) MaxCurrent(current int64) error {
|
||||
evse.current = current
|
||||
url := fmt.Sprintf("%s?current=%d", evse.apiURL(evseSetCurrent), current)
|
||||
return evse.checkError(evse.GetBody(url))
|
||||
return evse.get(url)
|
||||
}
|
||||
|
||||
var _ api.ChargeTimer = (*EVSEWifi)(nil)
|
||||
|
|
|
|||
|
|
@ -180,12 +180,8 @@ func (v *Identity) fetchToken(emobility bool) (tokenResponse, error) {
|
|||
}
|
||||
|
||||
req, err = request.New(http.MethodPost, "https://login.porsche.com/as/token.oauth2", strings.NewReader(dataAPIToken.Encode()), request.URLEncoding)
|
||||
|
||||
if err == nil {
|
||||
resp, err = v.Client.Do(req)
|
||||
if err == nil {
|
||||
err = request.DecodeJSON(resp, &pr)
|
||||
}
|
||||
err = v.DoJSON(req, &pr)
|
||||
}
|
||||
|
||||
if pr.AccessToken == "" || pr.ExpiresIn == 0 {
|
||||
|
|
@ -212,7 +208,6 @@ func (v *Identity) FindVehicle(accessTokens AccessTokens, vin string) (Vehicle,
|
|||
})
|
||||
|
||||
var vehicles []VehicleResponse
|
||||
|
||||
if err == nil {
|
||||
err = v.DoJSON(req, &vehicles)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -17,6 +18,7 @@ import (
|
|||
"github.com/andig/evcc/soc/server/auth"
|
||||
"github.com/andig/evcc/util"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/github"
|
||||
|
|
@ -214,6 +216,14 @@ func Run() {
|
|||
mux.HandleFunc("/login", handleLogin)
|
||||
mux.HandleFunc("/callback", handleCallback)
|
||||
|
||||
mux.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
// mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
// mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
// mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
|
||||
s := &http.Server{
|
||||
Addr: ":http",
|
||||
Handler: mux,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -67,9 +65,6 @@ func ReadBody(resp *http.Response) ([]byte, error) {
|
|||
return []byte{}, err
|
||||
}
|
||||
|
||||
// maintain body after reading
|
||||
resp.Body = io.NopCloser(bytes.NewBuffer(b))
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return b, StatusError{resp: resp}
|
||||
}
|
||||
|
|
@ -77,15 +72,6 @@ func ReadBody(resp *http.Response) ([]byte, error) {
|
|||
return b, nil
|
||||
}
|
||||
|
||||
// DecodeJSON reads HTTP response and decodes JSON body if error is nil
|
||||
func DecodeJSON(resp *http.Response, res interface{}) error {
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return StatusError{resp: resp}
|
||||
}
|
||||
|
||||
return json.NewDecoder(resp.Body).Decode(&res)
|
||||
}
|
||||
|
||||
// New builds and executes HTTP request and returns the response
|
||||
func New(method, uri string, data io.Reader, headers ...map[string]string) (*http.Request, error) {
|
||||
req, err := http.NewRequest(method, uri, data)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
|
@ -47,20 +48,31 @@ func (r *Helper) GetBody(url string) ([]byte, error) {
|
|||
return body, err
|
||||
}
|
||||
|
||||
// DoJSON executes HTTP request and decodes JSON response
|
||||
// decodeJSON reads HTTP response and decodes JSON body if error is nil
|
||||
func decodeJSON(resp *http.Response, res interface{}) error {
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return StatusError{resp: resp}
|
||||
}
|
||||
|
||||
return json.NewDecoder(resp.Body).Decode(&res)
|
||||
}
|
||||
|
||||
// DoJSON executes HTTP request and decodes JSON response. It returns a StatusError on response codes other than HTTP 2xx.
|
||||
func (r *Helper) DoJSON(req *http.Request, res interface{}) error {
|
||||
resp, err := r.Do(req)
|
||||
if err == nil {
|
||||
err = DecodeJSON(resp, &res)
|
||||
defer resp.Body.Close()
|
||||
err = decodeJSON(resp, &res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// GetJSON executes HTTP GET request and decodes JSON response
|
||||
// GetJSON executes HTTP GET request and decodes JSON response. It returns a StatusError on response codes other than HTTP 2xx.
|
||||
func (r *Helper) GetJSON(url string, res interface{}) error {
|
||||
resp, err := r.Get(url)
|
||||
if err == nil {
|
||||
err = DecodeJSON(resp, &res)
|
||||
defer resp.Body.Close()
|
||||
err = decodeJSON(resp, &res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue