mirror of https://github.com/elisescu/tty-share
Add support for joining a session from command line
parent
46e1bdaab2
commit
afc909a358
@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
ttyServer "github.com/elisescu/tty-share/server"
|
||||
"github.com/gorilla/websocket"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
type ttyShareClient struct {
|
||||
url string
|
||||
connection *websocket.Conn
|
||||
}
|
||||
|
||||
func newTtyShareClient(url string) *ttyShareClient {
|
||||
return &ttyShareClient{
|
||||
url: url,
|
||||
connection: nil,
|
||||
}
|
||||
}
|
||||
|
||||
type wsTextWriter struct {
|
||||
conn *websocket.Conn
|
||||
}
|
||||
|
||||
func (w *wsTextWriter) Write(data []byte) (n int, err error) {
|
||||
err = w.conn.WriteMessage(websocket.TextMessage, data)
|
||||
return len(data), err
|
||||
}
|
||||
|
||||
func (c *ttyShareClient) Run() (err error) {
|
||||
log.Printf("Starting tty-share client on %s", c.url)
|
||||
|
||||
resp, err := http.Get(c.url)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the path of the websockts route from the header
|
||||
wsPath := resp.Header.Get("TTYSHARE-WSPATH")
|
||||
|
||||
// Build the WS URL from the host part of the given http URL and the wsPath
|
||||
httpURL, err := url.Parse(c.url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
wsScheme := "ws"
|
||||
if httpURL.Scheme == "https" {
|
||||
wsScheme = "wss"
|
||||
}
|
||||
wsURL := wsScheme + "://" + httpURL.Host + wsPath
|
||||
|
||||
log.Printf("Connecting to WS URL: %s", wsURL)
|
||||
|
||||
conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
|
||||
if err != nil {
|
||||
log.Fatal("Cannot create the websocket connection:", err)
|
||||
}
|
||||
|
||||
state, err := terminal.MakeRaw(0)
|
||||
defer terminal.Restore(0, state)
|
||||
|
||||
c.connection = conn
|
||||
readLoop := func() {
|
||||
for {
|
||||
var msg ttyServer.MsgAll
|
||||
_, r, err := conn.NextReader()
|
||||
if err != nil {
|
||||
log.Infof("Connection closed: %s", err.Error())
|
||||
return
|
||||
}
|
||||
err = json.NewDecoder(r).Decode(&msg)
|
||||
if err != nil {
|
||||
log.Errorf("Cannot read JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
switch msg.Type {
|
||||
case ttyServer.MsgIDWrite:
|
||||
var msgWrite ttyServer.MsgTTYWrite
|
||||
err := json.Unmarshal(msg.Data, &msgWrite)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Cannot read JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
os.Stdout.Write(msgWrite.Data)
|
||||
case ttyServer.MsgIDWinSize:
|
||||
log.Debugf("Got Win Size msg")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeLoop := func() {
|
||||
ww := &wsTextWriter{
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
_, err := io.Copy(ttyServer.NewTTYProtocolWriter(ww), os.Stdin)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Finished io.Copy with %s", err.Error())
|
||||
}
|
||||
}
|
||||
go writeLoop()
|
||||
readLoop()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *ttyShareClient) Stop() {
|
||||
c.connection.Close()
|
||||
}
|
Loading…
Reference in New Issue