实现在线运行代码的一种方法


image-20221219173550349

通过http post方法将代码上传至服务器。

服务端:

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os/exec"
    "syscall"
    "time"
)

func main() {
    http.HandleFunc("/code-compile", codeCompile)
    server := &http.Server{
        Addr:           ":8080",
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    err := server.ListenAndServe()
    if err != nil {
        log.Fatal("listen and serve: ", err)
    }
}

func codeCompile(w http.ResponseWriter, r *http.Request) {
    var stdoutBuf, stderrBuf bytes.Buffer
    b, _ := ioutil.ReadAll(r.Body)
    fmt.Println(string(b))
    w.Header().Set("Content-Type", "text/html")

    cmd := exec.Command("bash", "-c", string(b))
    cmd.Stdout = &stdoutBuf
    cmd.Stderr = &stderrBuf
    cmd.Start()
    done := make(chan error)
    go func() {
        done <- cmd.Wait()
    }()

    // 设置超时,否则代码可能无限跑下去
    after := time.After(3 * time.Second)
    select {
    case <-after:
        cmd.Process.Signal(syscall.SIGINT)
        cmd.Process.Kill()
        w.Write([]byte("执行超时"))
    case <-done:
        // 将输出和错误都返回给请求
        w.Write(stdoutBuf.Bytes())
        w.Write(stderrBuf.Bytes())
    }
}

配合python或者go run指令等,并等待返回结果,超时强制中断。

image-20221219174548470

错误显示:

image-20221219174628898

可以结合docker,防止对本机造成重大影响:

$ docker run --rm ubuntu echo $USER
hqinglau