Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions components/engine/integration/plugin/authz/authz_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/docker/docker/client"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/internal/test/environment"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/authorization"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/skip"
Expand Down Expand Up @@ -382,6 +383,56 @@ func TestAuthZPluginEnsureLoadImportWorking(t *testing.T) {
assert.NilError(t, err)
}

func TestAuthzPluginEnsureContainerCopyToFrom(t *testing.T) {
defer setupTestV1(t)()
ctrl.reqRes.Allow = true
ctrl.resRes.Allow = true
d.StartWithBusybox(t, "--authorization-plugin="+testAuthZPlugin, "--authorization-plugin="+testAuthZPlugin)

dir, err := ioutil.TempDir("", t.Name())
assert.Assert(t, err)
defer os.RemoveAll(dir)

f, err := ioutil.TempFile(dir, "send")
assert.Assert(t, err)
defer f.Close()

buf := make([]byte, 1024)
fileSize := len(buf) * 1024 * 10
for written := 0; written < fileSize; {
n, err := f.Write(buf)
assert.Assert(t, err)
written += n
}

ctx := context.Background()
client, err := d.NewClient()
assert.Assert(t, err)

cID := container.Run(t, ctx, client)
defer client.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})

_, err = f.Seek(0, io.SeekStart)
assert.Assert(t, err)

srcInfo, err := archive.CopyInfoSourcePath(f.Name(), false)
assert.Assert(t, err)
srcArchive, err := archive.TarResource(srcInfo)
assert.Assert(t, err)
defer srcArchive.Close()

dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, archive.CopyInfo{Path: "/test"})
assert.Assert(t, err)

err = client.CopyToContainer(ctx, cID, dstDir, preparedArchive, types.CopyToContainerOptions{})
assert.Assert(t, err)

rdr, _, err := client.CopyFromContainer(ctx, cID, "/test")
assert.Assert(t, err)
_, err = io.Copy(ioutil.Discard, rdr)
assert.Assert(t, err)
}

func imageSave(client client.APIClient, path, image string) error {
ctx := context.Background()
responseReader, err := client.ImageSave(ctx, []string{image})
Expand Down
13 changes: 10 additions & 3 deletions components/engine/pkg/authorization/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand Down