Chromium Code Reviews| Index: experimental/webtry/webtry.go |
| diff --git a/experimental/webtry/webtry.go b/experimental/webtry/webtry.go |
| index d0588d558a5ce9e7e46a39af60b6c51311f68d9d..741a532ef90a1bc581d8e087aaaed5d47f742bee 100644 |
| --- a/experimental/webtry/webtry.go |
| +++ b/experimental/webtry/webtry.go |
| @@ -3,10 +3,12 @@ package main |
| import ( |
| "bytes" |
| "crypto/md5" |
| + "database/sql" |
| "encoding/base64" |
| "encoding/json" |
| "flag" |
| "fmt" |
| + _ "github.com/go-sql-driver/mysql" |
| "io/ioutil" |
| "log" |
| "net/http" |
| @@ -28,11 +30,15 @@ var ( |
| // index is the main index.html page we serve. |
| index []byte |
| + |
| + // db is the database, nil if we don't have an SQL database to store data into. |
| + db *sql.DB = nil |
| ) |
| // flags |
| var ( |
| useChroot = flag.Bool("use_chroot", false, "Run the compiled code in the schroot jail.") |
|
mtklein
2014/04/11 18:12:40
Think we should change this to something like runL
jcgregorio
2014/04/11 20:24:01
I actually prefer finer grained control. For examp
|
| + port = flag.Int("port", 8000, "Port to run the server on.") |
| ) |
| // lineNumbers adds #line numbering to the user's code. |
| @@ -63,6 +69,32 @@ func init() { |
| if err != nil { |
| panic(err) |
| } |
| + |
| + // Connect to MySQL server. First, get the password from the metadata server. |
| + // See https://developers.google.com/compute/docs/metadata#custom. |
| + req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/instance/attributes/password", nil) |
|
mtklein
2014/04/11 18:12:40
https?
jcgregorio
2014/04/11 20:24:01
The metadata server is http only.
On 2014/04/11 1
mtklein
2014/04/11 21:35:45
Doesn't that expose the DB password then?
On 2014
|
| + if err != nil { |
| + panic(err) |
| + } |
| + client := http.Client{} |
| + req.Header.Add("X-Google-Metadata-Request", "True") |
| + if resp, err := client.Do(req); err == nil { |
| + password, err := ioutil.ReadAll(resp.Body) |
| + if err != nil { |
| + log.Printf("ERROR: Failed to read password from metadata server: %q\n", err) |
| + panic(err) |
| + } |
| + // The IP address of the database is found here: |
| + // https://console.developers.google.com/project/31977622648/sql/instances/webtry/overview |
| + // And 3306 is the default port for MySQL. |
| + db, err = sql.Open("mysql", fmt.Sprintf("webtry:%s@tcp(173.194.83.52:3306)/webtry", password)) |
| + if err != nil { |
| + log.Printf("ERROR: Failed to open connection to SQL server: %q\n", err) |
| + panic(err) |
| + } |
| + } else { |
| + log.Printf("INFO: Failed to find metadata, unable to connect to MySQL server (Expected when running locally): %q\n", err) |
| + } |
| } |
| // userCode is used in template expansion. |
| @@ -155,6 +187,15 @@ func reportError(w http.ResponseWriter, r *http.Request, err error, message stri |
| w.Write(resp) |
| } |
| +func writeToDatabase(hash string, code string) { |
| + if db == nil { |
| + return |
| + } |
| + if _, err := db.Exec("INSERT INTO webtry (code, hash) VALUES(?, ?)", code, hash); err != nil { |
| + log.Printf("ERROR: Failed to insert code into database: %q\n", err) |
| + } |
| +} |
| + |
| // mainHandler handles the GET and POST of the main page. |
| func mainHandler(w http.ResponseWriter, r *http.Request) { |
| if r.Method == "GET" { |
| @@ -166,11 +207,13 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { |
| reportError(w, r, err, "Failed to read a request body.") |
| return |
| } |
| - hash, err := expandCode(LineNumbers(string(b))) |
| + code := string(b) |
|
mtklein
2014/04/11 18:12:40
gofmt? Seems some of this is tabs and some is spa
jcgregorio
2014/04/11 20:24:01
I've got my editor to run go fmt on Go files every
mtklein
2014/04/11 21:35:45
Ah. Good. I must have just been confused.
|
| + hash, err := expandCode(LineNumbers(code)) |
| if err != nil { |
| reportError(w, r, err, "Failed to write the code to compile.") |
| return |
| } |
| + writeToDatabase(hash, code) |
|
mtklein
2014/04/11 18:12:40
This has got me thinking about what should be goin
jcgregorio
2014/04/11 20:24:01
See previous comments on saving the image in the d
|
| message, err := doCmd(fmt.Sprintf(RESULT_COMPILE, hash, hash), true) |
| if err != nil { |
| reportError(w, r, err, "Failed to compile the code:\n"+message) |
| @@ -222,5 +265,5 @@ func main() { |
| flag.Parse() |
| http.HandleFunc("/", mainHandler) |
| - log.Fatal(http.ListenAndServe(":8000", nil)) |
| + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)) |
|
mtklein
2014/04/11 18:12:40
An alternative I see a lot in Go code is to make p
jcgregorio
2014/04/11 20:24:01
Done.
|
| } |