Git Product home page Git Product logo

wsep's Introduction

wsep

wsep is a high performance command execution protocol over WebSocket. It can be thought of as SSH over WebSockets without encryption.

The package offers the wsep.Execer interface so that local, SSH, and WebSocket execution can be interchanged. This is particular useful when testing.

Examples

Error handling is omitted for brevity.

Client

conn, _, _ := websocket.Dial(ctx, "ws://remote.exec.addr", nil)
defer conn.Close(websocket.StatusNormalClosure, "normal closure")

execer := wsep.RemoteExecer(conn)
process, _ := execer.Start(ctx, wsep.Command{
  Command: "cat",
  Args:    []string{"go.mod"},
  Stdin:   false,
})

go io.Copy(os.Stderr, process.Stderr())
go io.Copy(os.Stdout, process.Stdout())

process.Wait()

Server

func (s server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  conn, _ := websocket.Accept(w, r, nil)
  defer conn.Close(websocket.StatusNormalClosure, "normal closure")

  wsep.Serve(r.Context(), conn, wsep.LocalExecer{})
}

Development / Testing

Start a local executor:

go run ./dev/server

Start a client:

go run ./dev/client tty --id 1 -- bash
go run ./dev/client notty -- ls -la

Benchmarks

Local sh through a local wsep connection

$ head -c 100000000 /dev/urandom > /tmp/random; cat /tmp/random | pv | time ./bin/client notty -- sh -c "cat > /dev/null"

95.4MiB 0:00:00 [ 269MiB/s] [ <=>                                                                                  ]
./bin/client notty -- sh -c "cat > /dev/null"  0.32s user 0.31s system 31% cpu 2.019 total

Local sh directly

$ head -c 100000000 /dev/urandom > /tmp/random; cat /tmp/random | pv | time  sh -c "cat > /dev/null"

95.4MiB 0:00:00 [1.73GiB/s] [ <=>                                                                                  ]
sh -c "cat > /dev/null"  0.00s user 0.02s system 32% cpu 0.057 total

wsep's People

Contributors

ammario avatar cmoog avatar coadler avatar code-asher avatar jawnsy avatar johnstcn avatar spikecurtis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wsep's Issues

Basic benchmarks

Compare the speed of cat /dev/null locally vs over a local wsep connection.

Add Windows support

I'm opening this issue to discuss the best way to add Windows support, along with what I've found so far. I'd be happy to contribute a Windows implementation, including tests, but will require your guidance in order to do so effectively.

The current implementation of localexec_windows.go is an empty stub. By copying the implementation from localexec_unix.go and removing the non-portable Linux-specific parts (syscall, UID/GID), I was able to get a partial implementation running on Windows 10 under MinGW (Git Bash). I don't know if this is one of your near-term goals, but I thought you might be interested nonetheless.

Some caveats of the example I hacked together:

  • I didn't implement TTY support or Resize
  • A bunch of the integration tests are still failing
  • This required a modification to ./dev/client/main.go to remove the build tag and comment out the SIGWINCH signals

Here's what I have working so far:

$ go version
go version go1.15.5 windows/amd64
$ go run ./dev/client notty ls
browser
ci
client.go
client_test.go
dev
doc.go
exec.go
go.mod
go.sum
internal
LICENSE.txt
localexec.go
localexec_test.go
localexec_unix.go
localexec_windows.go
README.md
server.go
tty_test.go
$ go run ./dev/client notty ps ux
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
      716       1     716      10016  cons0    1051769 11:33:25 /usr/bin/bash
      810     716     810        252  cons0    1051769 11:35:48 /c/Program Files/Go/bin/go
      760       1     760      23620  cons1    1051769 11:33:42 /usr/bin/bash
      814     760     814      12756  cons1    1051769 11:37:38 /c/Program Files/Go/bin/go
      815       1     815       8208  ?        1051769 11:37:50 /usr/bin/ps

If I use the Command Prompt to start the server, then the results aren't as nice, however:

C:\projects\wsep>go run ./dev/server
2020-11-29 12:04:17 ERROR       failed to serve execer: start command: exec: "dir": executable file not found in %PATH%
2020/11/29 12:04:17 websocket: failed to marshal close frame: status code StatusAbnormalClosure cannot be set
exit status 2

A similar issue for PowerShell, too:

PS C:\projects\wsep> go run ./dev/server
2020-11-29 12:02:31 ERROR       failed to serve execer: start command: exec: "ls": executable file not found in %PATH%
2020/11/29 12:02:31 websocket: failed to marshal close frame: status code StatusAbnormalClosure cannot be set
2020-11-29 12:02:45 ERROR       failed to serve execer: start command: exec: "dir": executable file not found in %PATH%
2020/11/29 12:02:45 websocket: failed to marshal close frame: status code StatusAbnormalClosure cannot be set
exit status 2
PS C:\projects\wsep> dir

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        11/29/2020     11:22                .github
d-----        11/29/2020     11:22                browser
d-----        11/29/2020     11:22                ci
d-----        11/29/2020     11:22                dev
d-----        11/29/2020     11:22                internal
-a----        11/29/2020     11:22              7 .gitignore
-a----        11/29/2020     11:22           5276 client.go
-a----        11/29/2020     11:22           3552 client_test.go
-a----        11/29/2020     11:22            223 doc.go
-a----        11/29/2020     11:22           1813 exec.go
-a----        11/29/2020     11:22            432 go.mod
-a----        11/29/2020     11:22          28298 go.sum
-a----        11/29/2020     11:22           1083 LICENSE.txt
-a----        11/29/2020     11:22           1022 localexec.go
-a----        11/29/2020     11:22           3415 localexec_test.go
-a----        11/29/2020     11:22           2279 localexec_unix.go
-a----        11/29/2020     11:35           1381 localexec_windows.go
-a----        11/29/2020     11:22           2360 README.md
-a----        11/29/2020     11:22           3732 server.go
-a----        11/29/2020     11:22           1283 tty_test.go

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.