diff --git a/internal/protocol/gemini/gemini.go b/internal/protocol/gemini/gemini.go index 1a2d23a..6b6c604 100644 --- a/internal/protocol/gemini/gemini.go +++ b/internal/protocol/gemini/gemini.go @@ -100,10 +100,18 @@ func (p *Protocol) downloadWithRedirects(ctx context.Context, req *core.Download // Close the connection when the context is cancelled so any // blocking Read returns immediately instead of waiting for the - // 30-second deadline. + // 30-second deadline. The done channel bounds the goroutine to + // the lifetime of this call: when Download returns, defer + // close(done) lets the goroutine exit even if the parent context + // was never cancelled. + done := make(chan struct{}) + defer close(done) go func() { - <-ctx.Done() - conn.Close() + select { + case <-ctx.Done(): + conn.Close() + case <-done: + } }() // Send request: URL + CRLF