from 《Go语言.云动力》
1 package main 2 3 import ( 4 "io" 5 "log" 6 "net/http" 7 "os" 8 "os/exec" 9 "strconv" 10 ) 11 12 var uniq = make(chan int) 13 14 func init() { 15 go func() { 16 for i := 0; ; i++ { 17 uniq <- i 18 } 19 }() 20 } 21 22 func main() { 23 if err := os.Chdir(os.TempDir()); err != nil { 24 log.Fatal(err) 25 } 26 27 http.HandleFunc("/", FrontPage) 28 http.HandleFunc("/compile", Compile) 29 log.Fatal(http.ListenAndServe("127.0.0.1:1234", nil)) 30 } 31 32 func FrontPage(w http.ResponseWriter, _ *http.Request) { 33 w.Write([]byte(frontPage)) 34 } 35 36 func err(w http.ResponseWriter, e error) bool { 37 if e != nil { 38 w.Write([]byte(e.Error())) 39 return true 40 } 41 return false 42 } 43 44 func Compile(w http.ResponseWriter, req *http.Request) { 45 x := "play_" + strconv.Itoa(<-uniq) + ".go" 46 47 f, e := os.Create(x) 48 if err(w, e) { 49 return 50 } 51 52 defer os.Remove(x) 53 defer f.Close() 54 55 _, e = io.Copy(f, req.Body) 56 if err(w, e) { 57 return 58 } 59 f.Close() 60 61 cmd := exec.Command("go", "run", x) 62 o, e := cmd.CombinedOutput() 63 if err(w, e) { 64 return 65 } 66 67 w.Write(o) 68 } 69 70 const frontPage = `<!doctype html> 71 <html><head> 72 <script> 73 var req; 74 function compile(){ 75 var prog = document.getElementById("edit").value; 76 var req = new XMLHttpRequest (); 77 req.onreadystatechange = function() { 78 if (!req || req.readyState != 4) 79 return; 80 document.getElementById("output").innerHTML = req.responseText; 81 } 82 req.open("POST", "/compile", true); 83 req.setRequestHeader("Content-Type", "text/plain;charset=utf-8"); 84 req.send(prog); 85 } 86 87 </script> 88 </head> 89 <body> 90 <textarea rows="25" cols="80" id="edit" spellcheck="false"> 91 92 package main 93 import "fmt" 94 func main(){ 95 fmt.Println("hello, world") 96 } 97 </textarea> 98 <button onclick="compile();">run</button> 99 <div id="output"></div> 100 </body> 101 </html> 102 `