33package tunnel
44
55import (
6- "bytes"
76 "errors"
87 "fmt"
98 "html"
109 "io"
11- "io/ioutil"
1210 "net/http"
11+ "sync"
1312
1413 // imported per documentation - https://golang.org/pkg/net/http/pprof/
1514 _ "net/http/pprof"
@@ -77,16 +76,14 @@ func wsHandler(t *WSTunnelServer, w http.ResponseWriter, r *http.Request) {
7776 go func () {
7877 rs .remoteName , rs .remoteWhois = ipAddrLookup (t .Log , rs .remoteAddr )
7978 }()
80- // Set safety limits
81- ws .SetReadLimit (100 * 1024 * 1024 )
8279 // Start timeout handling
8380 wsSetPingHandler (t , ws , rs )
8481 // Create synchronization channel
8582 ch := make (chan int , 2 )
8683 // Spawn goroutine to read responses
87- go wsReader (rs , ws , t .WSTimeout , ch )
84+ go wsReader (rs , ws , t .WSTimeout , ch , & rs . readWG )
8885 // Send requests
89- wsWriter (rs , ws , ch )
86+ wsWriter (rs , ws , t . WSTimeout , ch )
9087}
9188
9289func wsSetPingHandler (t * WSTunnelServer , ws * websocket.Conn , rs * remoteServer ) {
@@ -111,7 +108,7 @@ func wsSetPingHandler(t *WSTunnelServer, ws *websocket.Conn, rs *remoteServer) {
111108}
112109
113110// Pick requests off the RemoteServer queue and send them into the tunnel
114- func wsWriter (rs * remoteServer , ws * websocket.Conn , ch chan int ) {
111+ func wsWriter (rs * remoteServer , ws * websocket.Conn , wsTimeout time. Duration , ch chan int ) {
115112 var req * remoteRequest
116113 var err error
117114 for {
@@ -136,7 +133,7 @@ func wsWriter(rs *remoteServer, ws *websocket.Conn, ch chan int) {
136133 continue
137134 }
138135 // write the request into the tunnel
139- ws .SetWriteDeadline (time .Now ().Add (time . Minute ))
136+ ws .SetWriteDeadline (time .Now ().Add (wsTimeout ))
140137 var w io.WriteCloser
141138 w , err = ws .NextWriter (websocket .BinaryMessage )
142139 // got an error, reply with a "hey, retry" to the request handler
@@ -170,11 +167,15 @@ func wsWriter(rs *remoteServer, ws *websocket.Conn, ch chan int) {
170167}
171168
172169// Read responses from the tunnel and fulfill pending requests
173- func wsReader (rs * remoteServer , ws * websocket.Conn , wsTimeout time.Duration , ch chan int ) {
170+ func wsReader (rs * remoteServer , ws * websocket.Conn , wsTimeout time.Duration , ch chan int , readWG * sync. WaitGroup ) {
174171 var err error
175172 logToken := cutToken (rs .token )
176173 // continue reading until we get an error
177174 for {
175+ // wait if another response is being sent
176+ readWG .Wait ()
177+ // increment the WaitGroup counter
178+ readWG .Add (1 )
178179 ws .SetReadDeadline (time.Time {}) // no timeout, there's the ping-pong for that
179180 // read a message from the tunnel
180181 var t int
@@ -195,34 +196,31 @@ func wsReader(rs *remoteServer, ws *websocket.Conn, wsTimeout time.Duration, ch
195196 if err != nil {
196197 break
197198 }
198- // read request itself, the size is limited by the SetReadLimit on the websocket
199- var buf []byte
200- buf , err = ioutil .ReadAll (r )
201- if err != nil {
202- break
203- }
204- rs .log .Info ("WS RCV" , "id" , id , "ws" , wsp (ws ), "len" , len (buf ))
205199 // try to match request
206200 rs .requestSetMutex .Lock ()
207201 req := rs .requestSet [id ]
208202 rs .lastActivity = time .Now ()
209203 rs .requestSetMutex .Unlock ()
210204 // let's see...
211205 if req != nil {
212- rb := responseBuffer {response : bytes . NewBuffer ( buf ) }
206+ rb := responseBuffer {response : r }
213207 // try to enqueue response
214208 select {
215209 case req .replyChan <- rb :
216210 // great!
211+ rs .log .Info ("WS RCV enqueued response" , "id" , id , "ws" , wsp (ws ))
217212 default :
213+ readWG .Done ()
218214 rs .log .Info ("WS RCV can't enqueue response" , "id" , id , "ws" , wsp (ws ))
219215 }
220216 } else {
217+ readWG .Done ()
221218 rs .log .Info ("%s #%d: WS RCV orphan response" , "id" , id , "ws" , wsp (ws ))
222219 }
223220 }
224221 // print error message
225222 if err != nil {
223+ readWG .Done ()
226224 rs .log .Info ("WS closing" , "token" , logToken , "err" , err .Error (), "ws" , wsp (ws ))
227225 }
228226 // close up shop
0 commit comments