// NewStreamReader returns a reader, which replays all the data generated by sw. // // The returned reader may be passed to Response.SetBodyStream. // // Close must be called on the returned reader after all the required data // has been read. Otherwise goroutine leak may occur. // // See also Response.SetBodyStreamWriter. func NewStreamReader(sw StreamWriter) io.ReadCloser { pc := fasthttputil.NewPipeConns() pw := pc.Conn1() pr := pc.Conn2() var bw *bufio.Writer v := streamWriterBufPool.Get() if v == nil { bw = bufio.NewWriter(pw) } else { bw = v.(*bufio.Writer) bw.Reset(pw) } go func() { defer func() { if r := recover(); r != nil { defaultLogger.Printf("panic in StreamWriter: %s\nStack trace:\n%s", r, debug.Stack()) } }() sw(bw) bw.Flush() pw.Close() streamWriterBufPool.Put(bw) }() return pr }
// NewStreamReader returns a reader, which replays all the data generated by sw. // // The returned reader may be passed to Response.SetBodyStream. // // Close must be called on the returned reader after all the required data // has been read. Otherwise goroutine leak may occur. // // See also Response.SetBodyStreamWriter. func NewStreamReader(sw StreamWriter) io.ReadCloser { pc := fasthttputil.NewPipeConns() pw := pc.Conn1() pr := pc.Conn2() var bw *bufio.Writer v := streamWriterBufPool.Get() if v == nil { bw = bufio.NewWriter(pw) } else { bw = v.(*bufio.Writer) bw.Reset(pw) } go func() { sw(bw) bw.Flush() pw.Close() streamWriterBufPool.Put(bw) }() return pr }