-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcopy.go
41 lines (38 loc) · 911 Bytes
/
copy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package websockify
import (
"fmt"
"go.uber.org/zap"
"io"
"net"
)
func ConnCopy(dst, src net.Conn, logger *zap.Logger, copyDone chan struct{}) {
defer func() {
select {
case <-copyDone:
return
default:
close(copyDone)
}
}()
_, err := io.Copy(dst, src)
if err != nil {
opErr, ok := err.(*net.OpError)
switch {
case ok && opErr.Op == "readfrom":
return
case ok && opErr.Op == "read":
return
default:
}
logger.Error(fmt.Sprintf("Failed to copy connection: %s", err),
zap.Field{Key: "src", String: src.RemoteAddr().String()},
zap.Field{Key: "dst", String: dst.RemoteAddr().String()})
}
}
func DuplexCopy(conn, rConn net.Conn, logger *zap.Logger) {
ch := make(chan struct{})
go ConnCopy(rConn, conn, logger, ch)
go ConnCopy(conn, rConn, logger, ch)
// rConn and conn will be closed by defer calls in handlers and proxyConn. There is nothing to do here.
<-ch
}