From 57706f218a68ed9843ed2d2ffc8c1ebe114b0631 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 (cherry picked from commit 7892cc91f9ed17f5a6e0348334ed09c8bdb3194f) --- 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)