diff --git a/internal/protocol/gopher/gopher.go b/internal/protocol/gopher/gopher.go index 17dd57b..6cfdc65 100644 --- a/internal/protocol/gopher/gopher.go +++ b/internal/protocol/gopher/gopher.go @@ -83,10 +83,18 @@ func (p *Protocol) Download(ctx context.Context, req *core.DownloadRequest) (*co // Close the connection when the context is cancelled so any // blocking Read returns immediately instead of waiting for the - // 30-second deadline. + // dial deadline. The done channel bounds the goroutine to the + // lifetime of Download: the goroutine exits either when the + // context fires (we close the conn) or when Download returns + // successfully and defer close(done) signals shutdown. + done := make(chan struct{}) + defer close(done) go func() { - <-ctx.Done() - conn.Close() + select { + case <-ctx.Done(): + conn.Close() + case <-done: + } }() // Send selector + CRLF