| // Copyright 2011 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "fmt" |
| "html/template" |
| "net/http" |
| "runtime" |
| "strings" |
| |
| "cloud.google.com/go/datastore" |
| ) |
| |
| const hostname = "play.golang.org" |
| |
| var editTemplate = template.Must(template.ParseFiles("edit.html")) |
| |
| type editData struct { |
| Snippet *snippet |
| Analytics bool |
| GoVersion string |
| Gotip bool |
| Examples []example |
| } |
| |
| func (s *server) handleEdit(w http.ResponseWriter, r *http.Request) { |
| w.Header().Set("Access-Control-Allow-Origin", "*") |
| if r.Method == "OPTIONS" { |
| // This is likely a pre-flight CORS request. |
| return |
| } |
| |
| // Redirect foo.play.golang.org to play.golang.org. |
| if strings.HasSuffix(r.Host, "."+hostname) { |
| http.Redirect(w, r, "https://"+hostname, http.StatusFound) |
| return |
| } |
| |
| // Serve 404 for /foo. |
| if r.URL.Path != "/" && !strings.HasPrefix(r.URL.Path, "/p/") { |
| http.NotFound(w, r) |
| return |
| } |
| |
| snip := &snippet{Body: []byte(s.examples.hello())} |
| if strings.HasPrefix(r.URL.Path, "/p/") { |
| id := r.URL.Path[3:] |
| serveText := false |
| if strings.HasSuffix(id, ".go") { |
| id = id[:len(id)-3] |
| serveText = true |
| } |
| |
| if err := s.db.GetSnippet(r.Context(), id, snip); err != nil { |
| if err != datastore.ErrNoSuchEntity { |
| s.log.Errorf("loading Snippet: %v", err) |
| } |
| http.Error(w, "Snippet not found", http.StatusNotFound) |
| return |
| } |
| if serveText { |
| if r.FormValue("download") == "true" { |
| w.Header().Set( |
| "Content-Disposition", fmt.Sprintf(`attachment; filename="%s.go"`, id), |
| ) |
| } |
| w.Header().Set("Content-type", "text/plain; charset=utf-8") |
| w.Write(snip.Body) |
| return |
| } |
| } |
| |
| if r.Host == hostname { |
| // The main playground is now on go.dev/play. |
| http.Redirect(w, r, "https://go.dev/play"+r.URL.Path, http.StatusFound) |
| return |
| } |
| |
| w.Header().Set("Content-Type", "text/html; charset=utf-8") |
| data := &editData{ |
| Snippet: snip, |
| GoVersion: runtime.Version(), |
| Gotip: s.gotip, |
| Examples: s.examples.examples, |
| } |
| if err := editTemplate.Execute(w, data); err != nil { |
| s.log.Errorf("editTemplate.Execute(w, %+v): %v", data, err) |
| return |
| } |
| } |