From 31bf943f18468f4b41633e4e15024862024aef6d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 13 May 2022 17:46:33 +0200 Subject: [PATCH] fix: hanging goroutine in get fileArchive handler Fixes #8957 The context was only checked while reading data. Not while writing data to the http connection. So since the data flow through an io.Pipe the closing didn't flowed through and left the writer open hanging. Co-authored-by: Antonio Navarro Perez --- core/commands/get.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/commands/get.go b/core/commands/get.go index 65ab46aa57c..7f687ed228b 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -61,6 +61,7 @@ may also specify the level of compression by specifying '-l=<1-9>'. return err }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx := req.Context cmplvl, err := getCompressOptions(req) if err != nil { return err @@ -73,7 +74,7 @@ may also specify the level of compression by specifying '-l=<1-9>'. p := path.New(req.Arguments[0]) - file, err := api.Unixfs().Get(req.Context, p) + file, err := api.Unixfs().Get(ctx, p) if err != nil { return err } @@ -90,6 +91,13 @@ may also specify the level of compression by specifying '-l=<1-9>'. if err != nil { return err } + go func() { + // We cannot defer a close in the response writer (like we should) + // Because the cmd framework outsmart us and doesn't call response + // if the context is over. + <-ctx.Done() + reader.Close() + }() return res.Emit(reader) }, @@ -273,7 +281,7 @@ func (i *identityWriteCloser) Close() error { return nil } -func fileArchive(f files.Node, name string, archive bool, compression int) (io.Reader, error) { +func fileArchive(f files.Node, name string, archive bool, compression int) (io.ReadCloser, error) { cleaned := gopath.Clean(name) _, filename := gopath.Split(cleaned)