From 1bc1c456984eab57193ef833d7732a2d62f90228 Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 10 Dec 2020 11:59:41 +0100 Subject: [PATCH] Fix some memory leaks caused by not closing HTTP request body (#516) --- cmd/health.go | 10 +++++++--- util/request/functions.go | 2 +- vehicle/bluelink/bluelink.go | 11 +++++++++-- vehicle/bmw.go | 1 + vehicle/id.go | 1 + vehicle/nissan.go | 2 ++ vehicle/porsche.go | 5 ++++- vehicle/vw.go | 5 ++++- vehicle/vw/identity.go | 10 +++++++++- 9 files changed, 38 insertions(+), 9 deletions(-) diff --git a/cmd/health.go b/cmd/health.go index 4f076a71a..060764348 100644 --- a/cmd/health.go +++ b/cmd/health.go @@ -47,9 +47,13 @@ func runHealth(cmd *cobra.Command, args []string) { var ok bool resp, err := client.Get(fmt.Sprintf("http+unix://%s/health", serviceName)) - if err == nil && resp.StatusCode == http.StatusOK { - log.INFO.Printf("health check ok") - ok = true + if err == nil { + resp.Body.Close() + + if resp.StatusCode == http.StatusOK { + log.INFO.Printf("health check ok") + ok = true + } } if !ok { diff --git a/util/request/functions.go b/util/request/functions.go index 2bbfbe1dd..efcb43a9d 100644 --- a/util/request/functions.go +++ b/util/request/functions.go @@ -51,7 +51,7 @@ func (e StatusError) HasStatus(codes ...int) bool { return false } -// ReadBody reads HTTP response and returns error on response codes other than HTTP 2xx +// ReadBody reads HTTP response and returns error on response codes other than HTTP 2xx. It closes the request body after reading. func ReadBody(resp *http.Response) ([]byte, error) { defer resp.Body.Close() diff --git a/vehicle/bluelink/bluelink.go b/vehicle/bluelink/bluelink.go index bb2d6913e..8bb20abff 100644 --- a/vehicle/bluelink/bluelink.go +++ b/vehicle/bluelink/bluelink.go @@ -146,7 +146,11 @@ func (v *API) getCookies() (cookieClient *request.Helper, err error) { v.config.CCSPServiceID, v.config.URI, ) - _, err = cookieClient.Get(uri) + + var resp *http.Response + if resp, err = cookieClient.Get(uri); err == nil { + resp.Body.Close() + } } return cookieClient, err @@ -159,7 +163,10 @@ func (v *API) setLanguage(cookieClient *request.Helper) error { req, err := request.New(http.MethodPost, v.config.URI+v.config.Lang, request.MarshalJSON(data), request.JSONEncoding) if err == nil { - _, err = cookieClient.Do(req) + var resp *http.Response + if resp, err = cookieClient.Do(req); err == nil { + resp.Body.Close() + } } return err diff --git a/vehicle/bmw.go b/vehicle/bmw.go index b68757bd6..24606a2fd 100644 --- a/vehicle/bmw.go +++ b/vehicle/bmw.go @@ -108,6 +108,7 @@ func (v *BMW) login(user, password string) error { if err != nil { return err } + defer resp.Body.Close() query, err := url.ParseQuery(resp.Header.Get("Location")) if err != nil { diff --git a/vehicle/id.go b/vehicle/id.go index adb7cf696..9c3dc453a 100644 --- a/vehicle/id.go +++ b/vehicle/id.go @@ -109,6 +109,7 @@ func (v *ID) authFlow() error { var vars vw.FormVars if err == nil { vars, err = vw.FormValues(resp.Body, "form#emailPasswordForm") + resp.Body.Close() } // POST identity.vwgroup.io/signin-service/v1/b7a5bb47-f875-47cf-ab83-2ba3bf6bb738@apps_vw-dilab_com/login/identifier diff --git a/vehicle/nissan.go b/vehicle/nissan.go index 2f1c84d83..a340c4b0a 100644 --- a/vehicle/nissan.go +++ b/vehicle/nissan.go @@ -190,6 +190,8 @@ func (v *Nissan) authFlow() error { v.Client.CheckRedirect = nil if err == nil { + resp.Body.Close() + var location *url.URL if location, err = url.Parse(resp.Header.Get("Location")); err == nil { if code = location.Query().Get("code"); code == "" { diff --git a/vehicle/porsche.go b/vehicle/porsche.go index 06853adf0..4469edc61 100644 --- a/vehicle/porsche.go +++ b/vehicle/porsche.go @@ -134,6 +134,7 @@ func (v *Porsche) authFlow() error { if err != nil { return err } + resp.Body.Close() query, err := url.ParseQuery(resp.Request.URL.RawQuery) if err != nil { @@ -161,9 +162,10 @@ func (v *Porsche) authFlow() error { } // process the auth so the session is authenticated - if _, err = client.Do(req); err != nil { + if resp, err = client.Do(req); err != nil { return err } + resp.Body.Close() var CodeVerifier, _ = cv.CreateCodeVerifier() codeChallenge := CodeVerifier.CodeChallengeS256() @@ -188,6 +190,7 @@ func (v *Porsche) authFlow() error { if err != nil { return err } + resp.Body.Close() query, err = url.ParseQuery(resp.Request.URL.RawQuery) if err != nil { diff --git a/vehicle/vw.go b/vehicle/vw.go index a23e08b19..7de0b427f 100644 --- a/vehicle/vw.go +++ b/vehicle/vw.go @@ -178,7 +178,10 @@ func (v *VW) Close() error { }) if err == nil { - _, err = v.Do(req) + var resp *http.Response + if resp, err = v.Do(req); err == nil { + resp.Body.Close() + } } return err diff --git a/vehicle/vw/identity.go b/vehicle/vw/identity.go index e5d6152c8..0b43f6594 100644 --- a/vehicle/vw/identity.go +++ b/vehicle/vw/identity.go @@ -23,6 +23,7 @@ type Identity struct { *http.Client } +// redirect follows HTTP redirect header if error is nil. Request body is closed. func (v *Identity) redirect(resp *http.Response, err error) (*http.Response, error) { if err == nil { uri := resp.Header.Get("Location") @@ -30,7 +31,9 @@ func (v *Identity) redirect(resp *http.Response, err error) (*http.Response, err return nil, errors.New("could not find expected HTTP redirect header\ngo to https://www.portal.volkswagen-we.com/ check account status") } - resp, err = v.Get(uri) + if resp, err = v.Get(uri); err == nil { + resp.Body.Close() + } } return resp, err @@ -44,6 +47,9 @@ func (v *Identity) Login(query url.Values, user, password string) (string, error // GET identity.vwgroup.io/oidc/v1/authorize?ui_locales=de&scope=openid%20profile%20birthdate%20nickname%20address%20phone%20cars%20mbb&response_type=code&state=gmiJOaB4&redirect_uri=https%3A%2F%2Fwww.portal.volkswagen-we.com%2Fportal%2Fweb%2Fguest%2Fcomplete-login&nonce=38042ee3-b7a7-43cf-a9c1-63d2f3f2d9f3&prompt=login&client_id=b7a5bb47-f875-47cf-ab83-2ba3bf6bb738@apps_vw-dilab_com uri := "https://identity.vwgroup.io/oidc/v1/authorize?" + query.Encode() resp, err := v.Get(uri) + if err == nil { + resp.Body.Close() + } // GET identity.vwgroup.io/signin-service/v1/signin/b7a5bb47-f875-47cf-ab83-2ba3bf6bb738@apps_vw-dilab_com?relayState=15404cb51c8b4cc5efeee1d2c2a73e5b41562faa if err == nil { @@ -52,6 +58,7 @@ func (v *Identity) Login(query url.Values, user, password string) (string, error if err == nil { vars, err = FormValues(resp.Body, "form#emailPasswordForm") + resp.Body.Close() } } @@ -79,6 +86,7 @@ func (v *Identity) Login(query url.Values, user, password string) (string, error if err == nil { vars, err = FormValues(resp.Body, "form#credentialsForm") + resp.Body.Close() } }