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 <antnavper@gmail.com>
Jorropo committed
May 13, 2022 at 17:46 UTC
7892cc91f9ed17f5a6e0348334ed09c8bdb3194f
1 file changed
+10
-2
core/commands/get.go
+10
-2
@@ -61,6 +61,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
61
return err
62
},
63
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
64
+ ctx := req.Context
65
cmplvl, err := getCompressOptions(req)
66
if err != nil {
67
return err
@@ -73,7 +74,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
74
75
p := path.New(req.Arguments[0])
76
76
- file, err := api.Unixfs().Get(req.Context, p)
77
+ file, err := api.Unixfs().Get(ctx, p)
78
if err != nil {
79
return err
80
}
@@ -90,6 +91,13 @@ may also specify the level of compression by specifying '-l=<1-9>'.
91
if err != nil {
92
return err
93
}
94
+ go func() {
95
+ // We cannot defer a close in the response writer (like we should)
96
+ // Because the cmd framework outsmart us and doesn't call response
97
+ // if the context is over.
98
+ <-ctx.Done()
99
+ reader.Close()
100
+ }()
101
102
return res.Emit(reader)
103
},
@@ -273,7 +281,7 @@ func (i *identityWriteCloser) Close() error {
281
return nil
282
}
283
276
-func fileArchive(f files.Node, name string, archive bool, compression int) (io.Reader, error) {
284
+func fileArchive(f files.Node, name string, archive bool, compression int) (io.ReadCloser, error) {
285
cleaned := gopath.Clean(name)
286
_, filename := gopath.Split(cleaned)
287