var RunScripts … var Environ … const msgLimit … const msgDelay … type Message … type Options … // NewHandler returns a websocket server which checks the origin of requests. func NewHandler(origin *url.URL) websocket.Server { … } // handshake checks the origin of a request during the websocket handshake. func handshake(c *websocket.Config, req *http.Request) error { … } // socketHandler handles the websocket connection for a given present session. // It handles transcoding Messages to and from JSON format, and starting // and killing processes. func socketHandler(c *websocket.Conn) { … } type process … // startProcess builds and runs the given program, sending its output // and end event as Messages on the provided channel. func startProcess(id, body string, dest chan<- *Message, opt *Options) *process { … } // end sends an "end" message to the client, containing the process id and the // given error value. It also removes the binary, if present. func (p *process) end(err error) { … } type killer … // limiter returns a channel that wraps the given channel. // It receives Messages from the given channel and sends them to the returned // channel until it passes msgLimit messages, at which point it will kill the // process and pass only the "end" message. // When the given channel is closed, or when the "end" message is received, // it closes the returned channel. func limiter(in <-chan *Message, p killer) <-chan *Message { … } // buffer returns a channel that wraps the given channel. It receives messages // from the given channel and sends them to the returned channel. // Message bodies are gathered over the period msgDelay and coalesced into a // single Message before they are passed on. Messages of the same kind are // coalesced; when a message of a different kind is received, any buffered // messages are flushed. When the given channel is closed, buffer flushes the // remaining buffered messages and closes the returned channel. // The timeAfter func should be time.After. It exists for testing. func buffer(in <-chan *Message, timeAfter func(time.Duration) <-chan time.Time) <-chan *Message { … } // Kill stops the process if it is running and waits for it to exit. func (p *process) Kill() { … } // shebang looks for a shebang ('#!') at the beginning of the passed string. // If found, it returns the path and args after the shebang. // args includes the command as args[0]. func shebang(body string) (path string, args []string) { … } // startProcess starts a given program given its path and passing the given body // to the command standard input. func (p *process) startProcess(path string, args []string, body string) error { … } // start builds and starts the given program, sending its output to p.out, // and stores the running *exec.Cmd in the run field. func (p *process) start(body string, opt *Options) error { … } // cmd builds an *exec.Cmd that writes its standard output and error to the // process' output channel. func (p *process) cmd(dir string, args ...string) *exec.Cmd { … } func isNacl() bool { … } // naclCmd returns an *exec.Cmd that executes bin under native client. func (p *process) naclCmd(bin string) (*exec.Cmd, error) { … } func packageName(body string) (string, error) { … } type messageWriter … func (w *messageWriter) Write(b []byte) (n int, err error) { … } // safeString returns b as a valid UTF-8 string. func safeString(b []byte) string { … }