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"
"log"
"net/http"
"regexp"
"sync"
)
@ -50,8 +51,8 @@ func NewAgent(publicId string,
agent: agentConn,
publicId: publicId,
client: clientConn,
agentAvailable: make(chan bool),
clientClosed: make(chan bool),
agentAvailable: make(chan bool, 1),
clientClosed: make(chan bool, 1),
}
}
@ -111,6 +112,7 @@ func (admin *Admin) Register(publicId string, conn *iowrappers.WebSocketConn) er
return err
}
agent.agentAvailable <- true
log.Printf("Agent registered: '%s'\n", publicId)
<-agent.clientClosed
return nil
}
@ -122,36 +124,56 @@ func (admin *Admin) Connect(publicId string, conn *iowrappers.WebSocketConn) err
return err
}
<-agent.agentAvailable
log.Println("Connecting websockets")
log.Printf("Connecting client and agent: '%s'\n", publicId)
iowrappers.SynchronizeStreams(agent.client, agent.agent)
agent.clientClosed <- true
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() {
admin := NewAdmin()
registrationService := WebSocketService{
handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) {
log.Println("Got registration connection")
err := admin.Register("abc123", conn)
publicId, err := parsePublicId(r.URL.Path)
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{
handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) {
log.Println("Got client connection")
err := admin.Connect("abc123", conn)
publicId, err := parsePublicId(r.URL.Path)
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("/client", clientService.handle)
http.HandleFunc("/register/", registrationService.handle)
http.HandleFunc("/client/", clientService.handle)
// Start HTTP server
fmt.Println("WebSocket server listening on :8000")

View File

@ -124,11 +124,11 @@ func handleWindowChange(session *ssh.Session, fd int) {
for range sigwinchCh {
width, height, err := term.GetSize(fd)
if err != nil {
log.Printf("Failed to get window size: %v", err)
log.Printf("Failed to get window size: %v\n", err)
continue
}
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) {
defer closeConnection(conn)
log.Printf("Connecting to '%s'\n", wsURL)
_wsConn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
if err != nil {
log.Println("WebSocket connection error:", err)
@ -39,8 +40,8 @@ func main() {
}
defer listener.Close()
log.Printf("TCP server listening on port %s", tcpPort)
log.Printf("Forwarding connections to WebSocket server at %s", wsURL)
log.Printf("TCP server listening on port %s\n", tcpPort)
log.Printf("Forwarding connections to WebSocket server at %s\n", wsURL)
for {
conn, err := listener.Accept()

View File

@ -14,7 +14,7 @@ func SynchronizeStreams(stream1, stream2 io.ReadWriter) {
}()
_, err := io.Copy(stream1, stream2)
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
}()
_, err := io.Copy(stream2, stream1)
log.Printf("Error %v", err)
log.Printf("Error %v\n", err)
}()
<-waitChannel