فهرست منبع

Splunk: limit the reader size on error responses

Before this patch, if a splunk endpoint returned a non-OK status, the
splunk driver would read the entire response body. This could lead to
excessive memory allocations. Instead put a cap on the amount the driver
will read from the response body.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff 7 سال پیش
والد
کامیت
7f14542ddd
1فایلهای تغییر یافته به همراه22 افزوده شده و 15 حذف شده
  1. 22 15
      daemon/logger/splunk/splunk.go

+ 22 - 15
daemon/logger/splunk/splunk.go

@@ -22,6 +22,7 @@ import (
 
 
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
 	"github.com/docker/docker/daemon/logger/loggerutils"
+	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/urlutil"
 	"github.com/docker/docker/pkg/urlutil"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
@@ -55,6 +56,8 @@ const (
 	defaultBufferMaximum = 10 * defaultPostMessagesBatchSize
 	defaultBufferMaximum = 10 * defaultPostMessagesBatchSize
 	// Number of messages allowed to be queued in the channel
 	// Number of messages allowed to be queued in the channel
 	defaultStreamChannelSize = 4 * defaultPostMessagesBatchSize
 	defaultStreamChannelSize = 4 * defaultPostMessagesBatchSize
+	// maxResponseSize is the max amount that will be read from an http response
+	maxResponseSize = 1024
 )
 )
 
 
 const (
 const (
@@ -500,20 +503,22 @@ func (l *splunkLogger) tryPostMessages(ctx context.Context, messages []*splunkMe
 	if l.gzipCompression {
 	if l.gzipCompression {
 		req.Header.Set("Content-Encoding", "gzip")
 		req.Header.Set("Content-Encoding", "gzip")
 	}
 	}
-	res, err := l.client.Do(req)
+	resp, err := l.client.Do(req)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	defer res.Body.Close()
-	if res.StatusCode != http.StatusOK {
-		var body []byte
-		body, err = ioutil.ReadAll(res.Body)
+	defer func() {
+		pools.Copy(ioutil.Discard, resp.Body)
+		resp.Body.Close()
+	}()
+	if resp.StatusCode != http.StatusOK {
+		rdr := io.LimitReader(resp.Body, maxResponseSize)
+		body, err := ioutil.ReadAll(rdr)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		return fmt.Errorf("%s: failed to send event - %s - %s", driverName, res.Status, body)
+		return fmt.Errorf("%s: failed to send event - %s - %s", driverName, resp.Status, string(body))
 	}
 	}
-	io.Copy(ioutil.Discard, res.Body)
 	return nil
 	return nil
 }
 }
 
 
@@ -596,20 +601,22 @@ func verifySplunkConnection(l *splunkLogger) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	res, err := l.client.Do(req)
+	resp, err := l.client.Do(req)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	if res.Body != nil {
-		defer res.Body.Close()
-	}
-	if res.StatusCode != http.StatusOK {
-		var body []byte
-		body, err = ioutil.ReadAll(res.Body)
+	defer func() {
+		pools.Copy(ioutil.Discard, resp.Body)
+		resp.Body.Close()
+	}()
+
+	if resp.StatusCode != http.StatusOK {
+		rdr := io.LimitReader(resp.Body, maxResponseSize)
+		body, err := ioutil.ReadAll(rdr)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		return fmt.Errorf("%s: failed to verify connection - %s - %s", driverName, res.Status, body)
+		return fmt.Errorf("%s: failed to verify connection - %s - %s", driverName, resp.Status, string(body))
 	}
 	}
 	return nil
 	return nil
 }
 }