forked from lxc/incus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmirror.go
68 lines (49 loc) · 1.62 KB
/
mirror.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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package ws
import (
"io"
"github.com/gorilla/websocket"
"github.com/lxc/incus/v6/shared/logger"
)
// Mirror takes a websocket and replicates all read/write to a ReadWriteCloser.
// Returns channels indicating when reads and writes are finished (respectively).
func Mirror(conn *websocket.Conn, rwc io.ReadWriteCloser) (chan error, chan error) {
chRead := MirrorRead(conn, rwc)
chWrite := MirrorWrite(conn, rwc)
return chRead, chWrite
}
// MirrorRead is a uni-directional mirror which replicates an io.Reader to a websocket.
func MirrorRead(conn *websocket.Conn, rc io.Reader) chan error {
chDone := make(chan error, 1)
if rc == nil {
close(chDone)
return chDone
}
logger.Debug("Websocket: Started read mirror", logger.Ctx{"address": conn.RemoteAddr().String()})
connRWC := NewWrapper(conn)
go func() {
_, err := io.Copy(connRWC, rc)
logger.Debug("Websocket: Stopped read mirror", logger.Ctx{"address": conn.RemoteAddr().String(), "err": err})
// Send write barrier.
connRWC.Close()
chDone <- err
close(chDone)
}()
return chDone
}
// MirrorWrite is a uni-directional mirror which replicates a websocket to an io.Writer.
func MirrorWrite(conn *websocket.Conn, wc io.Writer) chan error {
chDone := make(chan error, 1)
if wc == nil {
close(chDone)
return chDone
}
logger.Debug("Websocket: Started write mirror", logger.Ctx{"address": conn.RemoteAddr().String()})
connRWC := NewWrapper(conn)
go func() {
_, err := io.Copy(wc, connRWC)
logger.Debug("Websocket: Stopped write mirror", logger.Ctx{"address": conn.RemoteAddr().String(), "err": err})
chDone <- err
close(chDone)
}()
return chDone
}