package main import ( _ "embed" "flag" "net/http" "os" "os/exec" "strings" "github.com/creack/pty" "github.com/gorilla/websocket" "kumoly.io/lib/klog" "kumoly.io/lib/ksrv" "kumoly.io/lib/ksrv/engine" "kumoly.io/tools/goshell/public" ) //go:embed index.html var index string var tmpl *engine.Engine var servePublic = http.FileServer(http.FS(public.FS)) var ( flagAppName string flagAddr string flagShell string ) func init() { flag.StringVar(&flagAddr, "addr", ":8000", "address to bind") flag.StringVar(&flagShell, "shell", "bash", "the shell behind") } func main() { flag.Parse() server := ksrv.New() mux := http.NewServeMux() tmpl = engine.Must(engine.New("").Parse(index)) mux.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) { if r.URL.String() == "/" { tmpl.Execute(rw, App{flagAppName}) return } file, err := public.FS.Open(strings.TrimPrefix(r.URL.String(), "/")) if err != nil { klog.Debug(err) tmpl.Execute(rw, App{flagAppName}) return } stat, err := file.Stat() if err != nil || stat.IsDir() { klog.Debug(err) tmpl.Execute(rw, App{flagAppName}) return } servePublic.ServeHTTP(rw, r) }) server.Handle(mux).Listen(flagAddr).Serve() } type App struct { AppName string } type windowSize struct { Rows uint16 `json:"rows"` Cols uint16 `json:"cols"` X uint16 Y uint16 } var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } func handleWebsocket(w http.ResponseWriter, r *http.Request) { l := klog.Sub(ksrv.GetIP(r)) conn, err := upgrader.Upgrade(w, r, nil) if err != nil { l.Error("Unable to upgrade connection, err: ", err) return } cmd := exec.Command("/bin/bash", "-l") cmd.Env = append(os.Environ(), "TERM=xterm") pty.Winsize }