dynamic publicId now working with single connection to agent. Cleanup is not working yet.

This commit is contained in:
Erik Brakkee 2024-07-19 21:13:57 +02:00
parent e2c2cbd0ef
commit 8842c37a66
4 changed files with 40 additions and 17 deletions

View File

@ -6,6 +6,7 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"log" "log"
"net/http" "net/http"
"regexp"
"sync" "sync"
) )
@ -50,8 +51,8 @@ func NewAgent(publicId string,
agent: agentConn, agent: agentConn,
publicId: publicId, publicId: publicId,
client: clientConn, client: clientConn,
agentAvailable: make(chan bool), agentAvailable: make(chan bool, 1),
clientClosed: make(chan bool), clientClosed: make(chan bool, 1),
} }
} }
@ -111,6 +112,7 @@ func (admin *Admin) Register(publicId string, conn *iowrappers.WebSocketConn) er
return err return err
} }
agent.agentAvailable <- true agent.agentAvailable <- true
log.Printf("Agent registered: '%s'\n", publicId)
<-agent.clientClosed <-agent.clientClosed
return nil return nil
} }
@ -122,36 +124,56 @@ func (admin *Admin) Connect(publicId string, conn *iowrappers.WebSocketConn) err
return err return err
} }
<-agent.agentAvailable <-agent.agentAvailable
log.Println("Connecting websockets") log.Printf("Connecting client and agent: '%s'\n", publicId)
iowrappers.SynchronizeStreams(agent.client, agent.agent) iowrappers.SynchronizeStreams(agent.client, agent.agent)
agent.clientClosed <- true agent.clientClosed <- true
return nil return nil
} }
func parsePublicId(path string) (publicId string, _ error) {
pattern := regexp.MustCompile("^/[^/]+/([^/]+)$")
matches := pattern.FindStringSubmatch(path)
if len(matches) != 2 {
return "", fmt.Errorf("Invalid URL path '%s'", path)
}
return matches[1], nil
}
func main() { func main() {
admin := NewAdmin() admin := NewAdmin()
registrationService := WebSocketService{ registrationService := WebSocketService{
handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) { handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) {
log.Println("Got registration connection") publicId, err := parsePublicId(r.URL.Path)
err := admin.Register("abc123", conn)
if err != nil { if err != nil {
log.Printf("Error %v", err) log.Printf("Cannot parse public id from url: '%v'\n", err)
return
}
log.Printf("Got registration connection: '%s'\n", publicId)
err = admin.Register(publicId, conn)
if err != nil {
log.Printf("Error %v\n", err)
} }
}, },
} }
clientService := WebSocketService{ clientService := WebSocketService{
handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) { handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) {
log.Println("Got client connection") publicId, err := parsePublicId(r.URL.Path)
err := admin.Connect("abc123", conn)
if err != nil { if err != nil {
log.Printf("Error %v", err) log.Printf("Cannot parse public id from url: '%v'\n", err)
return
}
log.Printf("Got client connection: '%s'\n", publicId)
err = admin.Connect(publicId, conn)
if err != nil {
log.Printf("Error %v\n", err)
} }
}, },
} }
http.HandleFunc("/register", registrationService.handle) http.HandleFunc("/register/", registrationService.handle)
http.HandleFunc("/client", clientService.handle) http.HandleFunc("/client/", clientService.handle)
// Start HTTP server // Start HTTP server
fmt.Println("WebSocket server listening on :8000") fmt.Println("WebSocket server listening on :8000")

View File

@ -124,11 +124,11 @@ func handleWindowChange(session *ssh.Session, fd int) {
for range sigwinchCh { for range sigwinchCh {
width, height, err := term.GetSize(fd) width, height, err := term.GetSize(fd)
if err != nil { if err != nil {
log.Printf("Failed to get window size: %v", err) log.Printf("Failed to get window size: %v\n", err)
continue continue
} }
if err := session.WindowChange(height, width); err != nil { if err := session.WindowChange(height, width); err != nil {
log.Printf("Failed to send window change request: %v", err) log.Printf("Failed to send window change request: %v\n", err)
} }
} }
} }

View File

@ -18,6 +18,7 @@ func closeConnection(conn net.Conn) {
func handleConnection(conn net.Conn, wsURL string) { func handleConnection(conn net.Conn, wsURL string) {
defer closeConnection(conn) defer closeConnection(conn)
log.Printf("Connecting to '%s'\n", wsURL)
_wsConn, _, err := websocket.DefaultDialer.Dial(wsURL, nil) _wsConn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
if err != nil { if err != nil {
log.Println("WebSocket connection error:", err) log.Println("WebSocket connection error:", err)
@ -39,8 +40,8 @@ func main() {
} }
defer listener.Close() defer listener.Close()
log.Printf("TCP server listening on port %s", tcpPort) log.Printf("TCP server listening on port %s\n", tcpPort)
log.Printf("Forwarding connections to WebSocket server at %s", wsURL) log.Printf("Forwarding connections to WebSocket server at %s\n", wsURL)
for { for {
conn, err := listener.Accept() conn, err := listener.Accept()

View File

@ -14,7 +14,7 @@ func SynchronizeStreams(stream1, stream2 io.ReadWriter) {
}() }()
_, err := io.Copy(stream1, stream2) _, err := io.Copy(stream1, stream2)
if err != nil { if err != nil {
log.Printf("error %v", err) log.Printf("error %v\n", err)
} }
}() }()
@ -23,7 +23,7 @@ func SynchronizeStreams(stream1, stream2 io.ReadWriter) {
waitChannel <- true waitChannel <- true
}() }()
_, err := io.Copy(stream2, stream1) _, err := io.Copy(stream2, stream1)
log.Printf("Error %v", err) log.Printf("Error %v\n", err)
}() }()
<-waitChannel <-waitChannel