summaryrefslogtreecommitdiff
path: root/sockets.go
diff options
context:
space:
mode:
Diffstat (limited to 'sockets.go')
-rw-r--r--sockets.go90
1 files changed, 26 insertions, 64 deletions
diff --git a/sockets.go b/sockets.go
index 2ded258..319b548 100644
--- a/sockets.go
+++ b/sockets.go
@@ -1,79 +1,41 @@
1package main 1package main
2 2
3import ( 3import (
4 "context" 4 "fmt"
5 "io" 5 "io"
6 "log"
7 "net"
8 6
9 "github.com/gorilla/websocket" 7 "github.com/gorilla/websocket"
10) 8)
11 9
12func wsReader(wsconn *websocket.Conn, out chan []byte, ctx context.Context) { 10type WebsocketReadWriter struct {
13 for { 11 W *websocket.Conn
14 messageType, p, err := wsconn.ReadMessage()
15 if err != nil {
16 log.Printf("error: wsReader: %s", err)
17 return
18 }
19 if messageType != websocket.BinaryMessage {
20 log.Println("error: wsReader: only binary messages are supported")
21 continue
22 }
23 select {
24 case out <- p:
25 continue
26 case <-ctx.Done():
27 return
28 }
29 }
30} 12}
31 13
32func socketReader(proxyconn net.Conn, out chan []byte, ctx context.Context) { 14func (w *WebsocketReadWriter) Read(p []byte) (int, error) {
33 for { 15 t, m, err := w.W.ReadMessage()
34 readBuffer := make([]byte, 2048) 16 if err != nil {
35 17 return 0, fmt.Errorf("error reading websocket: %w", err)
36 i, err := proxyconn.Read(readBuffer) 18 }
37 if err != nil { 19 if t != websocket.BinaryMessage {
38 if err == io.EOF { 20 return 0, fmt.Errorf("error reading websocket: only binary messages are supported")
39 log.Println("info: socketReader: Disconnected") 21 }
40 } else { 22 if cap(p) < len(m) {
41 log.Printf("error: socketReader: %s", err) 23 return 0, fmt.Errorf("error reading websocket: outputbuffer too short for input")
42 } 24 }
43 return 25 if i := copy(p, m); i != len(m) {
44 } 26 return 0, fmt.Errorf("error reading websocket: copy failed %d of %d", i, len(m))
45
46 select {
47 case out <- readBuffer[:i]:
48 continue
49 case <-ctx.Done():
50 return
51 }
52 } 27 }
28 return len(m), nil
53} 29}
54 30
55func serviceBoth(wsconn *websocket.Conn, proxyconn net.Conn, ctx context.Context) { 31func (w *WebsocketReadWriter) Write(p []byte) (int, error) {
56 sc := make(chan []byte) 32 if err := w.W.WriteMessage(websocket.BinaryMessage, p); err != nil {
57 wsc := make(chan []byte) 33 return 0, fmt.Errorf("error writing websocket: %w", err)
58
59 go socketReader(proxyconn, sc, ctx)
60 go wsReader(wsconn, wsc, ctx)
61
62 for {
63 select {
64 case sd := <-sc:
65 if err := wsconn.WriteMessage(websocket.BinaryMessage, sd); err != nil {
66 log.Printf("error: serviceBoth: %s", err)
67 return
68 }
69
70 case wsd := <-wsc:
71 if _, err := proxyconn.Write(wsd); err != nil {
72 log.Printf("error: serviceBoth: %s", err)
73 return
74 }
75 case <-ctx.Done():
76 return
77 }
78 } 34 }
35 return len(p), nil
36}
37
38func serviceBoth(dst io.Writer, src io.Reader, errc chan<- error) {
39 _, err := io.Copy(dst, src)
40 errc <- err
79} 41}