golang.org/x/playground@v0.0.0-20230418134305-14ebe15bcd59/edit.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "html/template" 10 "net/http" 11 "runtime" 12 "strings" 13 14 "cloud.google.com/go/datastore" 15 ) 16 17 const hostname = "play.golang.org" 18 19 var editTemplate = template.Must(template.ParseFiles("edit.html")) 20 21 type editData struct { 22 Snippet *snippet 23 Share bool 24 Analytics bool 25 GoVersion string 26 Gotip bool 27 Examples []example 28 } 29 30 func (s *server) handleEdit(w http.ResponseWriter, r *http.Request) { 31 w.Header().Set("Access-Control-Allow-Origin", "*") 32 if r.Method == "OPTIONS" { 33 // This is likely a pre-flight CORS request. 34 return 35 } 36 37 // Redirect foo.play.golang.org to play.golang.org. 38 if strings.HasSuffix(r.Host, "."+hostname) { 39 http.Redirect(w, r, "https://"+hostname, http.StatusFound) 40 return 41 } 42 43 // Serve 404 for /foo. 44 if r.URL.Path != "/" && !strings.HasPrefix(r.URL.Path, "/p/") { 45 http.NotFound(w, r) 46 return 47 } 48 49 snip := &snippet{Body: []byte(s.examples.hello())} 50 if strings.HasPrefix(r.URL.Path, "/p/") { 51 if !allowShare(r) { 52 w.WriteHeader(http.StatusUnavailableForLegalReasons) 53 w.Write([]byte(`<h1>Unavailable For Legal Reasons</h1><p>Viewing and/or sharing code snippets is not available in your country for legal reasons. This message might also appear if your country is misdetected. If you believe this is an error, please <a href="https://golang.org/issue">file an issue</a>.</p>`)) 54 return 55 } 56 id := r.URL.Path[3:] 57 serveText := false 58 if strings.HasSuffix(id, ".go") { 59 id = id[:len(id)-3] 60 serveText = true 61 } 62 63 if err := s.db.GetSnippet(r.Context(), id, snip); err != nil { 64 if err != datastore.ErrNoSuchEntity { 65 s.log.Errorf("loading Snippet: %v", err) 66 } 67 http.Error(w, "Snippet not found", http.StatusNotFound) 68 return 69 } 70 if serveText { 71 if r.FormValue("download") == "true" { 72 w.Header().Set( 73 "Content-Disposition", fmt.Sprintf(`attachment; filename="%s.go"`, id), 74 ) 75 } 76 w.Header().Set("Content-type", "text/plain; charset=utf-8") 77 w.Write(snip.Body) 78 return 79 } 80 } 81 82 if r.Host == hostname { 83 // The main playground is now on go.dev/play. 84 http.Redirect(w, r, "https://go.dev/play"+r.URL.Path, http.StatusFound) 85 return 86 } 87 88 w.Header().Set("Content-Type", "text/html; charset=utf-8") 89 data := &editData{ 90 Snippet: snip, 91 Share: allowShare(r), 92 GoVersion: runtime.Version(), 93 Gotip: s.gotip, 94 Examples: s.examples.examples, 95 } 96 if err := editTemplate.Execute(w, data); err != nil { 97 s.log.Errorf("editTemplate.Execute(w, %+v): %v", data, err) 98 return 99 } 100 }