package main import ( "fmt" "io" "log" "net/http" "os" "os/exec" "path/filepath" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type test struct { path, output string } func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) r := gin.Default() // r.StaticFS("/", gin.Dir("./view/", false)) r.StaticFile("", filepath.Join("view", "index.html")) r.StaticFile("index.css", filepath.Join("view", "index.css")) // r.StaticFile("", filepath.Join("view", "index.html")) r.NoRoute(func(c *gin.Context) { c.String(http.StatusNotFound, "404") }) r.GET("/room/:id", func (c *gin.Context) { id := c.Param("id") }) r.POST("/answer", func (c *gin.Context) { // log.Panic("foo") language := c.PostForm("language"); if language == "" { c.JSON(http.StatusBadRequest, gin.H{"status": "error"}) log.Panic(fmt.Errorf("null language")) } fmt.Println(language) answer := c.PostForm("answer"); if answer == "" { c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "no answer"}) log.Panic(fmt.Errorf("null answer")) } uuid := uuid.NewString() dirPath := filepath.Join("sandbox", uuid) err := os.Mkdir(dirPath, 0755) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } defer os.RemoveAll(dirPath) programPath := filepath.Join("sandbox", uuid, "program") file, err := os.Create(programPath) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } _, err = file.Write([]byte(answer)) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } var tests []test testsDirPath := filepath.Join("test", "teste1") testDirs, err := os.ReadDir(testsDirPath) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } for _, testDir := range testDirs { testDirFilePath := filepath.Join(testsDirPath, testDir.Name()) inputOuptut, err := os.ReadDir(testDirFilePath) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } if len(inputOuptut) != 2 { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(len(inputOuptut) != 2) } inputPath := filepath.Join(testDirFilePath, inputOuptut[0].Name()) output, err := os.ReadFile(filepath.Join(testDirFilePath, inputOuptut[1].Name())) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } // fmt.Println("output:", string(output)) tests = append(tests, test{ path: inputPath, output: string(output), }) } for _, test := range tests { input, err := os.ReadFile(test.path) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } var cmd *exec.Cmd switch language { case "python": cmd = exec.Command("python", programPath) default: c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(fmt.Errorf("unregonized language: \"%s\"", language)) } stdin, _ := cmd.StdinPipe() io.WriteString(stdin, string(input)) stderr, _ := cmd.StderrPipe() stdout, _ := cmd.StdoutPipe() err = cmd.Start() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error"}) log.Panic(err) } errBuf, err := io.ReadAll(stderr) if err != nil { log.Fatal(err) } outBuf, err := io.ReadAll(stdout) if err != nil { log.Fatal(err) } err = cmd.Wait() if err != nil { c.JSON(http.StatusOK, gin.H{"status": "comp-exec", "message": string(errBuf)}) return } if string(outBuf) != test.output { msg := gin.H{"status": "wrong", "input": string(input), "output": string(outBuf), "expected": test.output} c.JSON(http.StatusOK, msg) return } } c.JSON(http.StatusOK, gin.H{"status": "pass", "id": 0, "success": "success"}) }) r.Run(":8001") }