package remotedialer import ( "context" "io/ioutil" "net/http" "time" "github.com/gorilla/websocket" "github.com/sirupsen/logrus" ) type ConnectAuthorizer func(proto, address string) bool func ClientConnect(wsURL string, headers http.Header, dialer *websocket.Dialer, auth ConnectAuthorizer, onConnect func(context.Context) error) { if err := connectToProxy(wsURL, headers, auth, dialer, onConnect); err != nil { logrus.WithError(err).Error("Failed to connect to proxy") time.Sleep(time.Duration(5) * time.Second) } } func connectToProxy(proxyURL string, headers http.Header, auth ConnectAuthorizer, dialer *websocket.Dialer, onConnect func(context.Context) error) error { logrus.WithField("url", proxyURL).Info("Connecting to proxy") if dialer == nil { dialer = &websocket.Dialer{HandshakeTimeout: 10 * time.Second} } ws, resp, err := dialer.Dial(proxyURL, headers) if err != nil { rb, err2 := ioutil.ReadAll(resp.Body) if err2 != nil { logrus.WithError(err).Errorf("Failed to connect to proxy. Response status: %v - %v. Couldn't read response body (err: %v)", resp.StatusCode, resp.Status, err2) } else { logrus.WithError(err).Errorf("Failed to connect to proxy. Response status: %v - %v. Response body: %s", resp.StatusCode, resp.Status, rb) } return err } defer ws.Close() defer resp.Body.Close() ctx, cancel := context.WithCancel(context.Background()) defer cancel() if onConnect != nil { if err := onConnect(ctx); err != nil { return err } } session := NewClientSession(auth, ws) _, err = session.Serve() session.Close() return err }