package httpd import ( "context" "net" "net/http" "path/filepath" "strings" "time" "net/http/pprof" "github.com/gorilla/mux" gorillaws "github.com/gorilla/websocket" "github.com/jumpserver/koko/pkg/config" "github.com/jumpserver/koko/pkg/logger" "github.com/kataras/neffos" "github.com/kataras/neffos/gorilla" ) var ( httpServer *http.Server Timeout = time.Duration(60) ) var upgrader = gorilla.Upgrader(gorillaws.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, }) var wsEvents = neffos.WithTimeout{ ReadTimeout: Timeout * time.Second, WriteTimeout: Timeout * time.Second, Namespaces: neffos.Namespaces{ "ssh": neffos.Events{ neffos.OnNamespaceConnected: OnNamespaceConnected, neffos.OnNamespaceDisconnect: OnNamespaceDisconnect, neffos.OnRoomJoined: func(c *neffos.NSConn, msg neffos.Message) error { return nil }, neffos.OnRoomLeft: func(c *neffos.NSConn, msg neffos.Message) error { return nil }, "data": OnDataHandler, "resize": OnResizeHandler, "host": OnHostHandler, "logout": OnLogoutHandler, "token": OnTokenHandler, "ping": OnPingHandler, }, "elfinder": neffos.Events{ neffos.OnNamespaceConnected: OnELFinderConnect, neffos.OnNamespaceDisconnect: OnELFinderDisconnect, "ping": OnPingHandler, }, }, } func StartHTTPServer() { conf := config.GetConf() sshWs := neffos.New(upgrader, wsEvents) sshWs.IDGenerator = func(w http.ResponseWriter, r *http.Request) string { return neffos.DefaultIDGenerator(w, r) } sshWs.OnUpgradeError = func(err error) { if ok := neffos.IsTryingToReconnect(err); ok { logger.Debug("A client was tried to reconnect") return } logger.Error("ERROR: ", err) } sshWs.OnConnect = func(c *neffos.Conn) error { if c.WasReconnected() { namespace := c.Socket().Request().Header.Get("X-Namespace") if namespace != "" { _, _ = c.Connect(context.TODO(), "ssh") } logger.Debugf("Connection %s reconnected, with tries: %d", c.ID(), c.ReconnectTries) } else { logger.Debug("A new ws connection arrive") } return nil } sshWs.OnDisconnect = func(c *neffos.Conn) { logger.Debug("Ws connection disconnect") } router := mux.NewRouter() fs := http.FileServer(http.Dir(filepath.Join(conf.RootPath, "static"))) subRouter := router.PathPrefix("/koko/").Subrouter() subRouter.PathPrefix("/static/").Handler(http.StripPrefix("/koko/static/", fs)) subRouter.Handle("/ws/", sshWs) elfinderRouter := subRouter.PathPrefix("/elfinder/").Subrouter() elfinderRouter.HandleFunc("/sftp/{host}/", AuthDecorator(sftpHostFinder)) elfinderRouter.HandleFunc("/sftp/", AuthDecorator(sftpFinder)) elfinderRouter.HandleFunc("/sftp/connector/{host}/", AuthDecorator(sftpHostConnectorView), ).Methods("GET", "POST") //router.PathPrefix("/coco/static/").Handler(http.StripPrefix("/coco/static/", fs)) //router.Handle("/socket.io/", sshWs) //router.HandleFunc("/coco/elfinder/sftp/{host}/", AuthDecorator(sftpHostFinder)) //router.HandleFunc("/coco/elfinder/sftp/", AuthDecorator(sftpFinder)) //router.HandleFunc("/coco/elfinder/sftp/connector/{host}/", // AuthDecorator(sftpHostConnectorView)).Methods("GET", "POST") if strings.ToUpper(conf.LogLevel) == "DEBUG" { router.PathPrefix("/debug/pprof/").HandlerFunc(pprof.Index) } addr := net.JoinHostPort(conf.BindHost, conf.HTTPPort) logger.Info("Start HTTP server at ", addr) httpServer = &http.Server{Addr: addr, Handler: router} logger.Fatal(httpServer.ListenAndServe()) } func StopHTTPServer() { _ = httpServer.Close() }