// forwardDataFrames moves data from one gRPC transport `Stream` to another in async fashion. // It returns an error channel. `nil` on it signifies everything was fine, anything else is a serious problem. func forwardDataFrames(srcStream *transport.Stream, dstStream *transport.Stream, dstTransport transportWriter) chan error { ret := make(chan error, 1) go func() { data := make([]byte, 4096) opt := &transport.Options{} for { n, err := srcStream.Read(data) if err != nil { // including io.EOF // Send nil to terminate the stream. opt.Last = true dstTransport.Write(dstStream, nil, opt) ret <- err break } if err := dstTransport.Write(dstStream, data[:n], opt); err != nil { ret <- err break } } close(ret) }() return ret }