@@ -20,73 +20,48 @@ import (
2020var DEBUG = os .Getenv ("DEBUG" ) == "1"
2121
2222type Response struct {
23- Output string `json:"output"`
24- Error string `json:"error"`
23+ Output string `json:"output"`
24+ Error string `json:"error"`
25+ ExecutionTime int64 `json:"time"`
26+ Code string `json:"code"`
2527}
2628
27- /**
28- * Pass STDIN to the Python interpreter
29- */
30- func execPython (timeout time.Duration , code * string ) (stdout string , stderr string ) {
31-
32- debug ("applying seccomp filter for Python" )
33-
34- ApplySyscallRestrictions ()
35-
36- debug ("building command context with %v timeout" , timeout )
37- ctx , cancel := context .WithTimeout (context .Background (), timeout )
38- defer cancel ()
39-
40- cmd := exec .CommandContext (ctx , "/usr/bin/python3" )
41- cmd .Stdin = strings .NewReader (* code )
42-
43- var errBuffer bytes.Buffer
44- cmd .Stderr = & errBuffer
45-
46- debug ("executing command ..." )
47- out , _ := cmd .Output ()
48-
49- if ctx .Err () == context .DeadlineExceeded {
50- debug ("command timed out" )
51- stderr = "command timed out"
52- return
53- }
54-
55- stdout = string (out )
56- stderr = errBuffer .String ()
57-
58- return
29+ func (r Response ) toJSON () string {
30+ data , _ := json .Marshal (r )
31+ return string (data )
5932}
6033
61- func execNode (timeout time.Duration , code * string ) (stdout string , stderr string ) {
62- debug ("applying seccomp filter for NodeJS" )
63-
34+ func execSandbox (interpreter string , timeout time.Duration , code * string ) * Response {
35+ res := Response {}
6436ApplySyscallRestrictions ()
6537
6638debug ("building command context with %v timeout" , timeout )
6739ctx , cancel := context .WithTimeout (context .Background (), timeout )
6840defer cancel ()
6941
70- cmd := exec .CommandContext (ctx , "node" )
42+ cmd := exec .CommandContext (ctx , interpreter )
7143cmd .Stdin = strings .NewReader (* code )
72- debug ( "stdin: %s" , * code )
44+ res . Code = * code
7345
7446var errBuffer bytes.Buffer
7547cmd .Stderr = & errBuffer
7648
7749debug ("executing command ..." )
50+ start := time .Now ()
7851out , _ := cmd .Output ()
52+ elapsed := time .Since (start )
53+
54+ res .ExecutionTime = elapsed .Milliseconds ()
7955
8056if ctx .Err () == context .DeadlineExceeded {
8157debug ("command timed out" )
82- stderr = "command timed out"
83- return
58+ res .Error = "command timed out"
8459}
8560
86- stdout = string (out )
87- stderr = errBuffer .String ()
61+ res . Output = string (out )
62+ res . Error = errBuffer .String ()
8863
89- return
64+ return & res
9065}
9166
9267func debug (msg string , args ... interface {}) {
@@ -127,22 +102,25 @@ func main() {
127102}
128103
129104var (
130- stdout string
131- stderr string
105+ interpreter string
106+ response Response
132107)
133108
134- if language == "python" || language == "py" {
135- stdout , stderr = execPython (duration , & data )
136- } else if language == "javascript" || language == "js" || language == "node" {
137- stdout , stderr = execNode (duration , & data )
138- }
139-
140- r , e := json .Marshal (Response {stdout , stderr })
141-
142- if e != nil {
143- fmt .Printf (`{"output": "", "error": "unexpected error code output to JSON!"}` )
109+ switch language {
110+ case "python" :
111+ case "py" :
112+ interpreter = "/usr/bin/python3"
113+ case "javascript" :
114+ case "js" :
115+ case "node" :
116+ interpreter = "node"
117+ default :
118+ response .Error = fmt .Sprintf ("unrecognized language %q" , language )
119+ fmt .Print (response .toJSON ())
144120return
145121}
146122
147- fmt .Print (string (r ))
123+ response = * execSandbox (interpreter , duration , & data )
124+
125+ fmt .Print (response .toJSON ())
148126}
0 commit comments