// New takes a websocket and creates a ShellClient object implementing the // engines.Shell interface. func New(ws *websocket.Conn) *ShellClient { stdinReader, stdin := ioext.BlockedPipe() tellOut := make(chan int, 10) tellErr := make(chan int, 10) stdout, stdoutWriter := ioext.AsyncPipe(shellconsts.ShellMaxPendingBytes, tellOut) stderr, stderrWriter := ioext.AsyncPipe(shellconsts.ShellMaxPendingBytes, tellErr) stdinReader.Unblock(shellconsts.ShellMaxPendingBytes) s := &ShellClient{ ws: ws, stdin: stdin, stdout: stdout, stderr: stderr, stdinReader: stdinReader, stdoutWriter: stdoutWriter, stderrWriter: stderrWriter, done: make(chan struct{}), } ws.SetReadLimit(shellconsts.ShellMaxMessageSize) ws.SetReadDeadline(time.Now().Add(shellconsts.ShellPongTimeout)) ws.SetPongHandler(s.pongHandler) go s.writeMessages() go s.readMessages() go s.sendPings() go s.sendAck(shellconsts.StreamStdout, tellOut) go s.sendAck(shellconsts.StreamStderr, tellErr) return s }
// NewShellHandler returns a new ShellHandler structure for that can // serve/expose a shell over a websocket. func NewShellHandler(ws *websocket.Conn, log *logrus.Entry) *ShellHandler { tellIn := make(chan int, 10) stdin, stdinWriter := ioext.AsyncPipe(shellconsts.ShellMaxPendingBytes, tellIn) stdoutReader, stdout := ioext.BlockedPipe() stderrReader, stderr := ioext.BlockedPipe() stdoutReader.Unblock(shellconsts.ShellMaxPendingBytes) stderrReader.Unblock(shellconsts.ShellMaxPendingBytes) s := &ShellHandler{ log: log, ws: ws, stdin: stdin, stdout: stdout, stderr: stderr, stdinWriter: stdinWriter, stdoutReader: stdoutReader, stderrReader: stderrReader, tellIn: tellIn, } ws.SetReadLimit(shellconsts.ShellMaxMessageSize) return s }