// subscribe all websocket clients to stream data // eg subscribe;3;stdout func wseventSubscribe(s *server, options string) error { args := strings.Split(options, ";") if len(args) != 2 { return errors.New("subscribe requires 2 args") } idstr := args[0] streamname := args[1] c, err := getCmd(s, idstr) if err != nil { return err } var stream liblush.OutStream switch streamname { case "stdout": stream = c.Stdout() case "stderr": stream = c.Stderr() default: return errors.New("unknown stream: " + streamname) } // proxy stream data w := newPrefixedWriter(&s.ctrlclients, []byte("stream;"+idstr+";"+streamname+";")) // do not close websocket stream when command exits wc := newNopWriteCloser(w) stream.Peeker().AddWriter(wc) return nil }
func connectCmdsById(s *server, fromId, toId liblush.CmdId, streamname string) error { var stream liblush.OutStream var to, from liblush.Cmd from = s.session.GetCommand(fromId) if from == nil { return errors.New("unknown command in from") } switch streamname { case "stdout": stream = from.Stdout() case "stderr": stream = from.Stderr() default: return errors.New("unknown stream") } if toId == 0 { return disconnectStream(stream) } to = s.session.GetCommand(toId) if to == nil { return errors.New("unknown command in to") } if pipedcmd(stream) != nil { // not strictly necessary but makes for simpler API. service to the // user! because that is how we roll. EaaS. return errors.New("already connected to another command") } stream.SetListener(to.Stdin()) return nil }
func disconnectStream(stream liblush.OutStream) error { var fwd liblush.Cmd fwd = pipedcmd(stream) if fwd == nil { return errors.New("no connected command found") } stream.SetListener(liblush.Devnull) return nil }
func handleWsStream(ctx *web.Context, idstr, streamname string) error { id, _ := liblush.ParseCmdId(idstr) s := ctx.User.(*server) c := s.session.GetCommand(id) if c == nil { return web.WebError{404, "no such command: " + idstr} } var stream liblush.OutStream switch streamname { case "stdout": stream = c.Stdout() case "stderr": stream = c.Stderr() default: return web.WebError{400, "No such stream: " + streamname} } stream.Peeker().AddWriter(ctx.WebsockConn) buf := make([]byte, 1) ctx.WebsockConn.Read(buf) return nil }
// return command that this stream pipes to, if any func pipedcmd(outs liblush.OutStream) liblush.Cmd { return iscmd(outs.GetListener()) }