func NewServer(config cli.Config) { server := server{ fileHandler: newFileServer(), socketHandler: newSocketServer(), } http.Handle("/socket.io/", server.socketHandler) http.Handle("/", server.fileHandler) logger.Notice("startup", "server", config.Listener()) log.Fatal(http.ListenAndServe(config.Listener(), nil)) }
func normalize(s string) string { if !utf8.ValidString(s) { v := make([]rune, 0, len(s)) for i, r := range s { if r == utf8.RuneError { _, size := utf8.DecodeRuneInString(s[i:]) if size == 1 { continue } } v = append(v, r) } s = string(v) logger.Notice("normalize", "emit", s) } return s }
func newSocketServer() http.Handler { sock, err := socketio.NewServer(nil) if err != nil { logger.Fatal("startup", "server", err) } sock.On("connection", func(so socketio.Socket) { conn := time.Now() so.Join(room) logger.Notice("connection", "socket", fmt.Sprintf("id:%s", so.Id())) so.On("help", func() { so.Emit("response", normalize("Host commands:")) for _, x := range whitelist { so.Emit("response", normalize(fmt.Sprintf(" $ %s", x))) } so.Emit("complete") }) so.On("request", func(msg string) { logger.Notice("request", "recieved", msg) var err error begin := time.Now() defer func() { if err == nil { so.Emit("complete", normalize("success")) logger.Info("request", "exec:complete", "success", begin) } else { so.Emit("complete", normalize(fmt.Sprintf("%s", err))) logger.Error("request", "exec:complete", err) } }() parts := strings.Split(msg, " ") if !whitelisted(parts[0]) { err = errors.New(fmt.Sprintf("Invalid command: %s", parts[0])) so.Emit("error", normalize(fmt.Sprintf("%s", err))) logger.Error("request", "whitelist", err) return } r, w := io.Pipe() logger.Info("request", "begin:exec", msg, begin) wait, err := exec.ForkTee(w, parts[0], parts[1:]...) if err != nil { so.Emit("error", normalize(fmt.Sprintf("%s", err))) } else { scanner := bufio.NewScanner(r) go func() { for scanner.Scan() { line := scanner.Text() so.Emit("response", normalize(line)) logger.DebugInfo("request", "response", line, begin) } }() _, err = wait() if err != nil { logger.Error("request", "wait", err) so.Emit("error", normalize(fmt.Sprintf("%s", err))) } } }) so.On("disconnection", func() { logger.Info("disconnection", "socket", fmt.Sprintf("id:%s", so.Id()), conn) }) }) sock.On("error", func(so socketio.Socket, err error) { logger.Error("error", "server", err) so.Emit("error", normalize(fmt.Sprintf("%s", err))) }) logger.DebugNotice("startup", "server", "SocketServer") return sock }