func newFileServer() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { h := &hijack{ResponseWriter: w, R: r} var status int begin := time.Now() defer func() { if p := recover(); p != nil { if p == h { status = p.(*hijack).Code } else { panic(p) } } logger.Request(r.Method, status, r.Proto, r.URL.Path, begin) if status != 200 { h.ResponseWriter.WriteHeader(status) if status == 404 { h.ResponseWriter.Write([]byte("Not Found")) } else { h.ResponseWriter.Write([]byte("Unknown Error")) } } }() logger.DebugNotice("startup", "server", "FileServer") http.FileServer(http.Dir(public)).ServeHTTP(h, r) }) }
func main() { // these will only be empty if 'help' or 'version' is passed to cli // TODO: abstract this to cli module if Config.Addr == "" || Config.Port == "" { os.Exit(0) } logger.DebugNotice("main", "server.NewServer", fmt.Sprintf("%#v", Config)) server.NewServer(Config) }
func Parse(args []string) (config Config) { app := cli.NewApp() app.Version = "0.0.1" app.Name = "socket-exec" app.Usage = "Socket.io server for executing on host via websockets." app.Flags = []cli.Flag{ cli.StringFlag{ Name: "addr, a", Value: "localhost", Usage: "listener address", EnvVar: "LISTEN_ADDR", }, cli.StringFlag{ Name: "port, p", Value: "3000", Usage: "listener port", EnvVar: "LISTEN_PORT", }, cli.BoolFlag{ Name: "debug, d", Usage: "print additional debug messages", EnvVar: "DEBUG", }, } app.Action = func(c *cli.Context) { config.Addr = c.String("addr") config.Port = c.String("port") logger.Debug = c.Bool("debug") if config.Addr == "" || config.Port == "" { logger.DebugNotice("cli", "Parse", fmt.Sprintf("%#v", config)) cli.ShowAppHelp(c) os.Exit(1) } } app.Run(args) return }
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 }