MM-25006: Fix occurences of unclosed http bodies (#14521)

* MM-25006: Fix occurences of unclosed http bodies

And while here, we also use ioutil.Discard to read the remaining
body instead of reading with ioutil.ReadAll which allocates a separate
byte buffer.

* Fix mistake

* Address review comments

Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Agniva De Sarker
2020-05-20 08:41:37 +05:30
коммит произвёл GitHub
родитель ee8bd4ece4
Коммит 15ed9a8f20
7 изменённых файлов: 42 добавлений и 17 удалений

Просмотреть файл

@@ -6,6 +6,8 @@ package api4
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil"
"net/http" "net/http"
"runtime" "runtime"
"strconv" "strconv"
@@ -432,6 +434,10 @@ func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(model.MapToJson(m))) w.Write([]byte(model.MapToJson(m)))
return return
} }
defer func() {
io.Copy(ioutil.Discard, res.Body)
res.Body.Close()
}()
location := res.Header.Get("Location") location := res.Header.Get("Location")
redirectLocationDataCache.AddWithExpiresInSecs(url, location, 3600) // Expires after 1 hour redirectLocationDataCache.AddWithExpiresInSecs(url, location, 3600) // Expires after 1 hour

Просмотреть файл

@@ -6,6 +6,7 @@ package app
import ( import (
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"time" "time"
@@ -177,6 +178,10 @@ func (a *App) TestSiteURL(siteURL string) *model.AppError {
if err != nil || res.StatusCode != 200 { if err != nil || res.StatusCode != 200 {
return model.NewAppError("testSiteURL", "app.admin.test_site_url.failure", nil, "", http.StatusBadRequest) return model.NewAppError("testSiteURL", "app.admin.test_site_url.failure", nil, "", http.StatusBadRequest)
} }
defer func() {
_, _ = io.Copy(ioutil.Discard, res.Body)
_ = res.Body.Close()
}()
return nil return nil
} }

Просмотреть файл

@@ -5,6 +5,7 @@ package app
import ( import (
"io" "io"
"io/ioutil"
"net/http" "net/http"
"path" "path"
"regexp" "regexp"
@@ -472,20 +473,24 @@ func (me *LoadTestProvider) UrlCommand(a *App, args *model.CommandArgs, message
} }
} }
var contents io.ReadCloser r, err := http.Get(url)
if r, err := http.Get(url); err != nil { if err != nil {
return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, err return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, err
} else if r.StatusCode > 400 { }
defer func() {
io.Copy(ioutil.Discard, r.Body)
r.Body.Close()
}()
if r.StatusCode > 400 {
return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, errors.Errorf("unexpected status code %d", r.StatusCode) return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, errors.Errorf("unexpected status code %d", r.StatusCode)
} else {
contents = r.Body
} }
bytes := make([]byte, 4000) bytes := make([]byte, 4000)
// break contents into 4000 byte posts // break contents into 4000 byte posts
for { for {
length, err := contents.Read(bytes) length, err := r.Body.Read(bytes)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return &model.CommandResponse{Text: "Encountered error reading file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, err return &model.CommandResponse{Text: "Encountered error reading file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, err
} }
@@ -522,16 +527,20 @@ func (me *LoadTestProvider) JsonCommand(a *App, args *model.CommandArgs, message
} }
} }
var contents io.ReadCloser r, err := http.Get(url)
if r, err := http.Get(url); err != nil { if err != nil {
return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, err return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, err
} else if r.StatusCode > 400 {
return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, errors.Errorf("unexpected status code %d", r.StatusCode)
} else {
contents = r.Body
} }
post := model.PostFromJson(contents) if r.StatusCode > 400 {
return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}, errors.Errorf("unexpected status code %d", r.StatusCode)
}
defer func() {
io.Copy(ioutil.Discard, r.Body)
r.Body.Close()
}()
post := model.PostFromJson(r.Body)
post.ChannelId = args.ChannelId post.ChannelId = args.ChannelId
post.UserId = args.UserId post.UserId = args.UserId
if post.Message == "" { if post.Message == "" {

Просмотреть файл

@@ -7,6 +7,7 @@ import (
"bytes" "bytes"
"image" "image"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
@@ -402,7 +403,10 @@ func (a *App) getLinkMetadata(requestURL string, timestamp int64, isNewPost bool
} }
if body != nil { if body != nil {
defer body.Close() defer func() {
io.Copy(ioutil.Discard, body)
body.Close()
}()
} }
if err == nil { if err == nil {

Просмотреть файл

@@ -106,7 +106,7 @@ func (s *Server) DoSecurityUpdateCheck() {
} }
body, err := ioutil.ReadAll(resBody.Body) body, err := ioutil.ReadAll(resBody.Body)
res.Body.Close() resBody.Body.Close()
if err != nil || resBody.StatusCode != 200 { if err != nil || resBody.StatusCode != 200 {
mlog.Error("Failed to read security bulletin details") mlog.Error("Failed to read security bulletin details")
return return

Просмотреть файл

@@ -65,7 +65,7 @@ type Client4 struct {
func closeBody(r *http.Response) { func closeBody(r *http.Response) {
if r.Body != nil { if r.Body != nil {
_, _ = ioutil.ReadAll(r.Body) _, _ = io.Copy(ioutil.Discard, r.Body)
_ = r.Body.Close() _ = r.Body.Close()
} }
} }

Просмотреть файл

@@ -5,6 +5,7 @@ package marketplace
import ( import (
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
@@ -79,7 +80,7 @@ func (c *Client) GetPlugin(filter *model.MarketplacePluginFilter, pluginVersion
// closeBody ensures the Body of an http.Response is properly closed. // closeBody ensures the Body of an http.Response is properly closed.
func closeBody(r *http.Response) { func closeBody(r *http.Response) {
if r.Body != nil { if r.Body != nil {
_, _ = ioutil.ReadAll(r.Body) _, _ = io.Copy(ioutil.Discard, r.Body)
_ = r.Body.Close() _ = r.Body.Close()
} }
} }