import (
"context"
+ "errors"
"fmt"
"io"
"sync/atomic"
},
}
}
+
+var (
+ ErrWrite = errors.New("ErrWrite")
+ ErrRead = errors.New("ErrRead")
+)
+
+// close reader by yourself
+func WithCtxCopy(ctx context.Context, callTree string, to time.Duration, w []io.WriteCloser, r io.Reader, panicf ...func(s string)) error {
+ rwc := WithCtxTO(ctx, callTree, to, w, r)
+ defer rwc.Close()
+ for buf := make([]byte, 2048); true; {
+ if n, e := rwc.Read(buf); n != 0 {
+ if n, e := rwc.Write(buf[:n]); n == 0 && e != nil {
+ if !errors.Is(e, io.EOF) {
+ return errors.Join(ErrWrite, e)
+ }
+ break
+ }
+ } else if e != nil {
+ if !errors.Is(e, io.EOF) {
+ return errors.Join(ErrRead, e)
+ }
+ break
+ }
+ }
+ return nil
+}
writeLoopTO = 1000
}
- rwc := pio.WithCtxTO(req.Context(), t.callTree, time.Duration(int(time.Millisecond)*writeLoopTO), ws, resReadCloser)
- defer rwc.Close()
-
- for buf := make([]byte, 2048); true; {
- if n, e := rwc.Read(buf); n != 0 {
- if n, e := rwc.Write(buf[:n]); n == 0 && e != nil {
- if !errors.Is(e, io.EOF) {
- err = errors.Join(err, ErrWriteRes, e)
- }
- break
- }
- } else if e != nil {
- if !errors.Is(e, io.EOF) {
- err = errors.Join(err, ErrReadRes, e)
- }
- break
- }
- }
+ // io copy
+ err = errors.Join(err, pio.WithCtxCopy(req.Context(), t.callTree, time.Duration(int(time.Millisecond)*writeLoopTO), ws, resReadCloser))
resp.Body.Close()