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  }