github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/core/lib/ioutils/utils.go (about) 1 package ioutils 2 3 import ( 4 "io" 5 logger "log" 6 7 lbuf "github.com/AntonOrnatskyi/goproxy/core/lib/buf" 8 ) 9 10 func IoBind(dst io.ReadWriteCloser, src io.ReadWriteCloser, fn func(err interface{}), log *logger.Logger) { 11 go func() { 12 defer func() { 13 if err := recover(); err != nil { 14 log.Printf("bind crashed %s", err) 15 } 16 }() 17 e1 := make(chan interface{}, 1) 18 e2 := make(chan interface{}, 1) 19 go func() { 20 defer func() { 21 if err := recover(); err != nil { 22 log.Printf("bind crashed %s", err) 23 } 24 }() 25 //_, err := io.Copy(dst, src) 26 err := ioCopy(dst, src) 27 e1 <- err 28 }() 29 go func() { 30 defer func() { 31 if err := recover(); err != nil { 32 log.Printf("bind crashed %s", err) 33 } 34 }() 35 //_, err := io.Copy(src, dst) 36 err := ioCopy(src, dst) 37 e2 <- err 38 }() 39 var err interface{} 40 select { 41 case err = <-e1: 42 //log.Printf("e1") 43 case err = <-e2: 44 //log.Printf("e2") 45 } 46 src.Close() 47 dst.Close() 48 if fn != nil { 49 fn(err) 50 } 51 }() 52 } 53 func ioCopy(dst io.ReadWriter, src io.ReadWriter) (err error) { 54 buf := lbuf.LeakyBuffer.Get() 55 defer lbuf.LeakyBuffer.Put(buf) 56 n := 0 57 for { 58 n, err = src.Read(buf) 59 if n > 0 { 60 if _, e := dst.Write(buf[0:n]); e != nil { 61 return e 62 } 63 } 64 if err != nil { 65 return 66 } 67 } 68 }