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>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ee8bd4ece4
Коммит
15ed9a8f20
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user