Limit authz response buffer

When the authz response buffer limit is hit, perform a flush.
This prevents excessive buffer sizes, especially on large responses
(e.g. `/containers/<id>/archive` or `/containers/<id>/export`).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 74f8e47352e71aad4015d8d9dea8f16e7a055863
Component: engine
This commit is contained in:
Brian Goff
2018-04-11 15:36:36 -04:00
parent 975c16f6d2
commit ad813c4199
2 changed files with 61 additions and 3 deletions
@@ -47,6 +47,8 @@ func NewResponseModifier(rw http.ResponseWriter) ResponseModifier {
return &responseModifier{rw: rw, header: make(http.Header)}
}
const maxBufferSize = 64 * 1024
// responseModifier is used as an adapter to http.ResponseWriter in order to manipulate and explore
// the http request/response from docker daemon
type responseModifier struct {
@@ -116,11 +118,13 @@ func (rm *responseModifier) OverrideHeader(b []byte) error {
// Write stores the byte array inside content
func (rm *responseModifier) Write(b []byte) (int, error) {
if rm.hijacked {
return rm.rw.Write(b)
}
if len(rm.body)+len(b) > maxBufferSize {
rm.Flush()
}
rm.body = append(rm.body, b...)
return len(b), nil
}
@@ -192,11 +196,14 @@ func (rm *responseModifier) FlushAll() error {
var err error
if len(rm.body) > 0 {
// Write body
_, err = rm.rw.Write(rm.body)
var n int
n, err = rm.rw.Write(rm.body)
// TODO(@cpuguy83): there is now a relatively small buffer limit, instead of discarding our buffer here and
// allocating again later this should just keep using the same buffer and track the buffer position (like a bytes.Buffer with a fixed size)
rm.body = rm.body[n:]
}
// Clean previous data
rm.body = nil
rm.statusCode = 0
rm.header = http.Header{}
return err