diff --git a/go.mod b/go.mod index eb9b11f..2a89463 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,7 @@ -module bingus-exec +module git.merith.xyz/merith-tk/reso-execution go 1.21.3 -require ( - github.com/gorilla/mux v1.8.1 - github.com/gorilla/websocket v1.5.1 -) +require github.com/gorilla/websocket v1.5.1 require golang.org/x/net v0.22.0 // indirect diff --git a/go.sum b/go.sum index a1d0af7..b477da7 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= diff --git a/main.go b/main.go index c153673..7a6937b 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,15 @@ 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" @@ -22,6 +32,9 @@ var Upgrader = websocket.Upgrader{ 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) @@ -33,6 +46,7 @@ func main() { } 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) @@ -51,8 +65,40 @@ func HandleWs(w http.ResponseWriter, r *http.Request) { // seperate message into chunks by newline msg := strings.Split(string(message), "\n") - sendMessage := handleCase(msg[0], strings.Join(msg[1:], "\n")) - // send the message back to the client - err = c.WriteMessage(websocket.TextMessage, []byte(sendMessage.String())) + 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]) + } + }() +} diff --git a/output.go b/output.go new file mode 100644 index 0000000..c5c87a6 --- /dev/null +++ b/output.go @@ -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() diff --git a/runtime.go b/runtime.go index ba86e6e..b9a7eca 100644 --- a/runtime.go +++ b/runtime.go @@ -3,6 +3,7 @@ package main import ( "log" "os/exec" + "path/filepath" "strings" // import file writer @@ -10,54 +11,59 @@ import ( // import websocket ) -func handleCase(caseName string, data string) strings.Builder { - // get the first line of the message from the client - // strip : from the caseName - caseName = strings.Replace(caseName, ":", "", -1) - returnData := strings.Builder{} +func handleCase(caseName, data string) string { + caseName = strings.ReplaceAll(caseName, "\n", "") + caseName = strings.ReplaceAll(caseName, ":", "") + + log.Println("Handling case", caseName) switch caseName { - case "py", "python", "python3": - log.Println("Python is not supported yet") - returnData = runPython(data) - case "go", "golang": - log.Println("Golang is not supported yet") - // returnData = runGo(data) - case "js", "javascript": - log.Println("Javascript is not supported yet") - // returnData = runJs(data) - case "cpp", "c++": - log.Println("C++ is not supported yet") + case "python", "python3", "py": + runPython(data) } - return returnData + return "" } -func runPython(data string) strings.Builder { - // write Data to `./workspace/main.py` - file, err := os.Create("./workspace/main.py") +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 } - defer file.Close() - file.WriteString(data) // find python, python3, or py in the system - fname, err := exec.LookPath("python3") - if err != nil { - log.Println("Python not found") + // 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 } - // run the python file - cmd := exec.Command(fname, "./workspace/main.py") - // write output to value, and then return it - cmdOut := &strings.Builder{} - cmd.Stdout = cmdOut - cmdErr := &strings.Builder{} - cmd.Stderr = cmdErr - cmd.Run() + cmd := exec.Command(fname, "./main.py") + cmd.Dir = filepath.ToSlash("./workspace/") + // set the command's stdout to the pipe writer + cmd.Stdout = pyWriter - // combine the output and error - cmdOut.WriteString(cmdErr.String()) - // print the output to the console - log.Println(cmdOut.String()) - return *cmdOut + // set the command's stderr to the pipe writer + cmd.Stderr = pyWriter + + // start the command + cmd.Run() + log.Println("Python runtime finished") } diff --git a/tmp/build-errors.log b/tmp/build-errors.log index 6ccc48a..09a09eb 100644 --- a/tmp/build-errors.log +++ b/tmp/build-errors.log @@ -1 +1 @@ -exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file +exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file diff --git a/tmp/main.exe b/tmp/main.exe index aaf86f2..b704648 100644 Binary files a/tmp/main.exe and b/tmp/main.exe differ diff --git a/workspace/main.py b/workspace/main.py index 5e1e9e0..4d779d5 100644 --- a/workspace/main.py +++ b/workspace/main.py @@ -1,4 +1,4 @@ import time -for i in range(50): +for i in range(10): print(i) time.sleep(0.5) \ No newline at end of file