begin work on "test client"
This commit is contained in:
parent
66268e6702
commit
0a563d8b02
9 changed files with 113 additions and 279 deletions
100
cmd/client/main.go
Normal file
100
cmd/client/main.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, os.Interrupt)
|
||||
|
||||
host := "127.0.0.1:5000"
|
||||
langURL := fmt.Sprintf("ws://%s/lang", host)
|
||||
cmdURL := fmt.Sprintf("ws://%s/cmd", host)
|
||||
debugURL := fmt.Sprintf("ws://%s/debug", host)
|
||||
execURL := fmt.Sprintf("ws://%s/", host)
|
||||
|
||||
execConn, err := connectWebSocket(execURL)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to lang websocket:", err)
|
||||
}
|
||||
defer execConn.Close()
|
||||
|
||||
langConn, err := connectWebSocket(langURL)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to lang websocket:", err)
|
||||
}
|
||||
defer langConn.Close()
|
||||
|
||||
cmdConn, err := connectWebSocket(cmdURL)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to cmd websocket:", err)
|
||||
}
|
||||
defer cmdConn.Close()
|
||||
|
||||
debugConn, err := connectWebSocket(debugURL)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to debug websocket:", err)
|
||||
}
|
||||
defer debugConn.Close()
|
||||
|
||||
done := make(chan struct{})
|
||||
go readMessages(langConn, "lang", done)
|
||||
go readMessages(cmdConn, "cmd", done)
|
||||
go readMessages(debugConn, "debug", done)
|
||||
// Read the contents of source.txt
|
||||
sourceFile := "source.txt"
|
||||
sourceData, err := ioutil.ReadFile(sourceFile)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to read source file:", err)
|
||||
}
|
||||
|
||||
// create execConn off of / endpoint
|
||||
|
||||
// Send the contents over the lang websocket
|
||||
err = execConn.WriteMessage(websocket.TextMessage, sourceData)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to send source data over lang websocket:", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-interrupt:
|
||||
fmt.Println("Interrupt signal received, closing connections...")
|
||||
close(done)
|
||||
time.Sleep(1 * time.Second)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func connectWebSocket(urlStr string) (*websocket.Conn, error) {
|
||||
u, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func readMessages(conn *websocket.Conn, name string, done chan struct{}) {
|
||||
for {
|
||||
_, message, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("Error reading message from", name, "websocket:", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Received message from %s: %s\n", name, message)
|
||||
}
|
||||
}
|
104
cmd/server/main.go
Normal file
104
cmd/server/main.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
fn fetch_python_location() -> String {
|
||||
let output = Command::new("which python")
|
||||
.output()
|
||||
.expect("Failed to execute command");
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
output.trim().to_string()
|
||||
output
|
||||
}
|
||||
*/
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const (
|
||||
WS_HOST = "0.0.0.0"
|
||||
WS_PORT = 5000
|
||||
)
|
||||
|
||||
var Upgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool { return true },
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", HandleWs)
|
||||
|
||||
// output handlers
|
||||
http.HandleFunc("/lang", HandleLang)
|
||||
|
||||
// if ./workspace/ directory does not exist, create it
|
||||
if _, err := os.Stat("./workspace/"); os.IsNotExist(err) {
|
||||
os.Mkdir("./workspace/", 0755)
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", WS_HOST, WS_PORT)
|
||||
log.Println("Server started at", addr)
|
||||
log.Fatal(http.ListenAndServe(addr, nil))
|
||||
}
|
||||
|
||||
func HandleWs(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("[/] Connection from", r.RemoteAddr)
|
||||
c, err := Upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Print("upgrade:", err)
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
for {
|
||||
// get the first line of the message from the client
|
||||
_, message, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
// print the message to the console
|
||||
log.Printf("recv: %s", message)
|
||||
|
||||
// seperate message into chunks by newline
|
||||
msg := strings.Split(string(message), "\n")
|
||||
handleCase(msg[0], strings.Join(msg[1:], "\n"))
|
||||
|
||||
c.WriteMessage(websocket.TextMessage, []byte("Forwarding to output handler: "+msg[0]+"\n"))
|
||||
}
|
||||
}
|
||||
|
||||
func HandleLang(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("[/lang] Connection from", r.RemoteAddr)
|
||||
// upgrade the connection to a websocket
|
||||
c, err := Upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// defer c.Close()
|
||||
c.WriteMessage(websocket.TextMessage, []byte("Connected to output handler"))
|
||||
go func() {
|
||||
for {
|
||||
// wait for message from client
|
||||
_, message, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("Error reading from client", err)
|
||||
break
|
||||
}
|
||||
// convert message to string
|
||||
msg := string(message)
|
||||
log.Println("Received message from client:", msg)
|
||||
// convert pyReader to string
|
||||
newstr := make([]byte, 1024)
|
||||
n, err := pyReader.Read(newstr)
|
||||
if err != nil {
|
||||
log.Println("Error reading from pyReader")
|
||||
break
|
||||
}
|
||||
c.WriteMessage(websocket.TextMessage, newstr[:n])
|
||||
}
|
||||
}()
|
||||
}
|
8
cmd/server/output.go
Normal file
8
cmd/server/output.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// pythonOut is a channel that will be written to by the python runtime via exec.Command
|
||||
var pyReader, pyWriter = io.Pipe()
|
69
cmd/server/runtime.go
Normal file
69
cmd/server/runtime.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
// import file writer
|
||||
"os"
|
||||
// import websocket
|
||||
)
|
||||
|
||||
func handleCase(caseName, data string) string {
|
||||
// caseName = strings.ReplaceAll(caseName, "\n", "")
|
||||
caseName = strings.ReplaceAll(caseName, ":", "")
|
||||
|
||||
log.Println("Handling case", caseName)
|
||||
switch caseName {
|
||||
case "python", "python3", "py":
|
||||
runPython(data)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func runPython(data string) {
|
||||
log.Println("Running python")
|
||||
// create a file in the workspace directory
|
||||
f, err := os.Create("./workspace/main.py")
|
||||
if err != nil {
|
||||
log.Println("Error creating file")
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// write the data to the file
|
||||
_, err = f.WriteString(data)
|
||||
if err != nil {
|
||||
log.Println("Error writing to file")
|
||||
return
|
||||
}
|
||||
|
||||
// find python, python3, or py in the system
|
||||
fname, err := exec.LookPath("python3")
|
||||
if err != nil {
|
||||
log.Println("Python not found")
|
||||
} else {
|
||||
log.Println("Python found at", fname)
|
||||
}
|
||||
// fname := "C:\\Users\\zachd\\scoop\\shims\\python3.exe"
|
||||
|
||||
// if main.py does not exist, return
|
||||
if _, err := os.Stat("./workspace/main.py"); os.IsNotExist(err) {
|
||||
log.Println("File does not exist")
|
||||
return
|
||||
}
|
||||
|
||||
cmd := exec.Command(fname, "./main.py")
|
||||
cmd.Dir = filepath.ToSlash("./workspace/")
|
||||
// set the command's stdout to the pipe writer
|
||||
cmd.Stdout = pyWriter
|
||||
|
||||
// set the command's stderr to the pipe writer
|
||||
cmd.Stderr = pyWriter
|
||||
|
||||
// start the command
|
||||
cmd.Run()
|
||||
log.Println("Python runtime finished")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue