fix(http): drain and close HTTP response bodies EE-5280 (#8716)

pull/8723/head
andres-portainer 2023-03-27 15:14:16 -03:00 committed by GitHub
parent 3635df89dc
commit 814fc9dfc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 45 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import (
"crypto/tls" "crypto/tls"
"errors" "errors"
"fmt" "fmt"
"io"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@ -42,7 +43,9 @@ func GetAgentVersionAndPlatform(endpointUrl string, tlsConfig *tls.Config) (port
if err != nil { if err != nil {
return 0, "", err return 0, "", err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusNoContent { if resp.StatusCode != http.StatusNoContent {
return 0, "", fmt.Errorf("Failed request with status %d", resp.StatusCode) return 0, "", fmt.Errorf("Failed request with status %d", resp.StatusCode)

View File

@ -113,7 +113,9 @@ func (c FDOOwnerClient) PutDeviceSVI(info ServiceInfo) error {
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return errors.New(http.StatusText(resp.StatusCode)) return errors.New(http.StatusText(resp.StatusCode))
@ -132,7 +134,9 @@ func (c FDOOwnerClient) PutDeviceSVIRaw(info url.Values, body []byte) error {
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return errors.New(http.StatusText(resp.StatusCode)) return errors.New(http.StatusText(resp.StatusCode))
@ -151,7 +155,9 @@ func (c FDOOwnerClient) GetVouchers() ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, errors.New(http.StatusText(resp.StatusCode)) return nil, errors.New(http.StatusText(resp.StatusCode))
@ -182,7 +188,9 @@ func (c FDOOwnerClient) DeleteVoucher(guid string) error {
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return errors.New(http.StatusText(resp.StatusCode)) return errors.New(http.StatusText(resp.StatusCode))
@ -201,7 +209,9 @@ func (c FDOOwnerClient) GetDeviceSVI(guid string) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
@ -225,7 +235,9 @@ func (c FDOOwnerClient) DeleteDeviceSVI(id string) error {
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return errors.New(http.StatusText(resp.StatusCode)) return errors.New(http.StatusText(resp.StatusCode))

View File

@ -33,10 +33,13 @@ func (service *Service) Authorization(configuration portainer.OpenAMTConfigurati
if err != nil { if err != nil {
return "", err return "", err
} }
defer response.Body.Close()
responseBody, readErr := io.ReadAll(response.Body) responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil { if readErr != nil {
return "", readErr return "", readErr
} }
errorResponse := parseError(responseBody) errorResponse := parseError(responseBody)
if errorResponse != nil { if errorResponse != nil {
return "", errorResponse return "", errorResponse

View File

@ -128,6 +128,7 @@ func (service *Service) getCIRACertificate(configuration portainer.OpenAMTConfig
if err != nil { if err != nil {
return "", err return "", err
} }
defer response.Body.Close()
if response.StatusCode != http.StatusOK { if response.StatusCode != http.StatusOK {
return "", fmt.Errorf("unexpected status code %s", response.Status) return "", fmt.Errorf("unexpected status code %s", response.Status)
@ -137,6 +138,8 @@ func (service *Service) getCIRACertificate(configuration portainer.OpenAMTConfig
if err != nil { if err != nil {
return "", err return "", err
} }
block, _ := pem.Decode(certificate) block, _ := pem.Decode(certificate)
return base64.StdEncoding.EncodeToString(block.Bytes), nil return base64.StdEncoding.EncodeToString(block.Bytes), nil
} }

View File

@ -103,6 +103,8 @@ func (service *Service) executeSaveRequest(method string, url string, token stri
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer response.Body.Close()
responseBody, readErr := io.ReadAll(response.Body) responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil { if readErr != nil {
return nil, readErr return nil, readErr
@ -132,6 +134,8 @@ func (service *Service) executeGetRequest(url string, token string) ([]byte, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer response.Body.Close()
responseBody, readErr := io.ReadAll(response.Body) responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil { if readErr != nil {
return nil, readErr return nil, readErr
@ -141,10 +145,12 @@ func (service *Service) executeGetRequest(url string, token string) ([]byte, err
if response.StatusCode == http.StatusNotFound { if response.StatusCode == http.StatusNotFound {
return nil, nil return nil, nil
} }
errorResponse := parseError(responseBody) errorResponse := parseError(responseBody)
if errorResponse != nil { if errorResponse != nil {
return nil, errorResponse return nil, errorResponse
} }
return nil, fmt.Errorf("unexpected status code %s", response.Status) return nil, fmt.Errorf("unexpected status code %s", response.Status)
} }

View File

@ -53,6 +53,7 @@ func Test_backupHandlerWithoutPassword_shouldCreateATarballArchive(t *testing.T)
response := w.Result() response := w.Result()
body, _ := io.ReadAll(response.Body) body, _ := io.ReadAll(response.Body)
response.Body.Close()
tmpdir := t.TempDir() tmpdir := t.TempDir()
@ -89,6 +90,7 @@ func Test_backupHandlerWithPassword_shouldCreateEncryptedATarballArchive(t *test
response := w.Result() response := w.Result()
body, _ := io.ReadAll(response.Body) body, _ := io.ReadAll(response.Body)
response.Body.Close()
tmpdir := t.TempDir() tmpdir := t.TempDir()

View File

@ -99,6 +99,8 @@ func backup(t *testing.T, h *Handler, password string) []byte {
response := w.Result() response := w.Result()
archive, _ := io.ReadAll(response.Body) archive, _ := io.ReadAll(response.Body)
response.Body.Close()
return archive return archive
} }

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -128,7 +129,6 @@ func getDockerHubToken(httpClient *client.HTTPClient, registry *portainer.Regist
} }
func getDockerHubLimits(httpClient *client.HTTPClient, token string) (*dockerhubStatusResponse, error) { func getDockerHubLimits(httpClient *client.HTTPClient, token string) (*dockerhubStatusResponse, error) {
requestURL := "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" requestURL := "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest"
req, err := http.NewRequest(http.MethodHead, requestURL, nil) req, err := http.NewRequest(http.MethodHead, requestURL, nil)
@ -142,7 +142,9 @@ func getDockerHubLimits(httpClient *client.HTTPClient, token string) (*dockerhub
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, errors.New("failed fetching dockerhub limits") return nil, errors.New("failed fetching dockerhub limits")

View File

@ -121,12 +121,13 @@ func getResource(token string, configuration *portainer.OAuthSettings) (map[stri
client := &http.Client{} client := &http.Client{}
req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Authorization", "Bearer "+token)
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -68,6 +68,7 @@ func (hbpm *helmBinaryPackageManager) SearchRepo(searchRepoOpts options.SearchRe
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get index file") return nil, errors.Wrap(err, "failed to get index file")
} }
defer resp.Body.Close()
var file File var file File
err = yaml.NewDecoder(resp.Body).Decode(&file) err = yaml.NewDecoder(resp.Body).Decode(&file)