1) You're calling Read() directly and don't need to use functions that strictly accept io.Reader - then just implement ReadContext:
func (rc ioContextReader) ReadContext(ctx context.Context, p []byte) (n int, err error) {
done := make(chan struct{})
go func() {
n, err = rc.Reader.Read(p)
close(done)
}()
select {
case <-ctx.Done():
return 0, ctx.Err()
case <-done:
return n, err
}
}
Otherwise, just wrap the ioContextReader with another ioContextReader: reader = ioContextReader(ctx, r)