Documentation
¶
Overview ¶
Package play provides callable APIs and HTTP handlers to format and run Go code, similar to Go playground but using HTTP instead of WebSocket.
For HTTP API, this package expose two handlers: HTTPHandleFormat and HTTPHandleRun. Both HTTP APIs accept JSON content type, with the following request format,
{ "goversion": <string>, // For run only. "without_race": <boolean>, // For run only. "body": <string> }
The "goversion" field define the Go tools and toolchain version to be used to compile the code. The default "goversion" is defined as global variable GoVersion in this package. If "without_race" is true, the Run command will not run with "-race" option. The "body" field contains the Go code to be formatted or run.
Both return the following JSON response format,
{ "code": <integer, HTTP status code>, "name": <string, error type>, "message": <string, optional message>, "data": <string> }
For the HTTPHandleFormat, the response "data" contains the formatted Go code. For the HTTPHandleRun, the response "data" contains the output from running the Go code, the "message" contains an error pre-Run, like bad request or file system related error.
As exceptional, the Run and HTTPHandleRun accept the following request for running program inside custom "go.mod",
{ "unsafe_run": <path> }
The "unsafe_run" define the path to directory relative to HTTP server working directory. Once request accepted it will change the directory into "unsafe_run" first and then run "go run ." directly. Go code that executed inside "unsafe_run" should be not modifiable and safe from mallicious execution.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var GoVersion = `1.23.2`
GoVersion define the Go tool version for go.mod to be used to run the code.
var Timeout = 10 * time.Second
Timeout define the maximum time the program can be run until it get terminated.
Functions ¶
func Format ¶
Format the Go code in the [Request.Body] and return the result to out. Any syntax error on the code will be returned as error.
Example ¶
const codeIndentMissingImport = ` package main func main() { fmt.Println("Hello, world") } ` var req = Request{ Body: codeIndentMissingImport, } var ( out []byte err error ) out, err = Format(req) if err != nil { log.Fatal(err) } fmt.Printf("%s", out)
Output: package main import "fmt" func main() { fmt.Println("Hello, world") }
func HTTPHandleFormat ¶
func HTTPHandleFormat(httpresw http.ResponseWriter, httpreq *http.Request)
HTTPHandleFormat define the HTTP handler for formating Go code.
Example ¶
var mux = http.NewServeMux() mux.HandleFunc(`POST /api/play/format`, HTTPHandleFormat) const codeIndentMissingImport = ` package main func main() { fmt.Println("Hello, world") } ` var req = Request{ Body: codeIndentMissingImport, } var ( rawbody []byte err error ) rawbody, err = json.Marshal(&req) if err != nil { log.Fatal(err) } var resprec = httptest.NewRecorder() var httpreq = httptest.NewRequest(`POST`, `/api/play/format`, bytes.NewReader(rawbody)) httpreq.Header.Set(`Content-Type`, `application/json`) mux.ServeHTTP(resprec, httpreq) var resp = resprec.Result() rawbody, err = io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Printf(`%s`, rawbody)
Output: {"data":"package main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"Hello, world\")\n}\n","code":200}
func HTTPHandleRun ¶
func HTTPHandleRun(httpresw http.ResponseWriter, httpreq *http.Request)
HTTPHandleRun define the HTTP handler for running Go code. Each client is identified by unique cookie, so if two Run requests come from the same client, the previous Run will be cancelled.
Example ¶
var mux = http.NewServeMux() mux.HandleFunc(`POST /api/play/run`, HTTPHandleRun) const codeRun = ` package main import "fmt" func main() { fmt.Println("Hello, world") } ` var req = Request{ Body: codeRun, } var ( rawbody []byte err error ) rawbody, err = json.Marshal(&req) if err != nil { log.Fatal(err) } var resprec = httptest.NewRecorder() var httpreq = httptest.NewRequest(`POST`, `/api/play/run`, bytes.NewReader(rawbody)) httpreq.Header.Set(`Content-Type`, `application/json`) mux.ServeHTTP(resprec, httpreq) var resp = resprec.Result() rawbody, err = io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Printf(`%s`, rawbody)
Output: {"data":"Hello, world\n","code":200}
func Run ¶
Run the Go code in the [Request.Body].
Example ¶
const codeRun = ` package main import "fmt" func main() { fmt.Println("Hello, world") }` var req = Request{ Body: codeRun, } var ( out []byte err error ) out, err = Run(&req) if err != nil { fmt.Printf(`error: %s`, err) } fmt.Printf(`%s`, out)
Output: Hello, world
Types ¶
type Request ¶
type Request struct { // The Go version that will be used in go.mod. GoVersion string `json:"goversion"` // Body contains the Go code to be Format-ed or Run. Body string `json:"body"` // UnsafeRun define the working directory where "go run ." will be // executed directly. UnsafeRun string `json:"unsafe_run"` // WithoutRace define option opt out "-race" when running Go code. WithoutRace bool `json:"without_race"` // contains filtered or unexported fields }