diff options
| -rw-r--r-- | .gcloudignore | 2 | ||||
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | app.yaml | 17 | ||||
| -rw-r--r-- | appengine.go | 49 | ||||
| -rw-r--r-- | local.go | 34 |
5 files changed, 48 insertions, 57 deletions
diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 0000000..0030d4f --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,2 @@ +.gcloudignore +.git diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d8c2c11..0000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -last-change -*.orig -*.rej @@ -1,12 +1,14 @@ service: tour -runtime: go -api_version: go1 +runtime: go111 -default_expiration: "7d" +env_variables: + GOLANGORG_CHECK_COUNTRY: true -handlers: +default_expiration: "7d" # Keep these static file handlers in sync with local.go. +# They're here for improved latency across global regions. +handlers: - url: /favicon.ico static_files: static/img/favicon.ico upload: static/img/favicon.ico @@ -16,11 +18,4 @@ handlers: secure: always - url: /static static_dir: static - application_readable: true secure: always - -- url: /(.*|list|lesson/.*|compile|fmt|script\.js) - script: _go_app - secure: always - -nobuild_files: (solutions|content)/.* diff --git a/appengine.go b/appengine.go index 4767a2c..5db885b 100644 --- a/appengine.go +++ b/appengine.go @@ -2,56 +2,43 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build appengine - package main import ( "bufio" "bytes" "io" + "log" "net/http" - "strings" - - "appengine" + "os" _ "golang.org/x/tools/playground" ) -const runUrl = "https://golang.org/compile" - -func init() { - http.Handle("/lesson/", hstsHandler(lessonHandler)) - http.Handle("/", hstsHandler(rootHandler)) +func gaeMain() { + prepContent = gaePrepContent + socketAddr = gaeSocketAddr if err := initTour(".", "HTTPTransport"); err != nil { - panic(err) + log.Fatal(err) } -} -func rootHandler(w http.ResponseWriter, r *http.Request) { - c := appengine.NewContext(r) - if err := renderUI(w); err != nil { - c.Criticalf("UI render: %v", err) - } -} + http.Handle("/", hstsHandler(rootHandler)) + http.Handle("/lesson/", hstsHandler(lessonHandler)) -func lessonHandler(w http.ResponseWriter, r *http.Request) { - c := appengine.NewContext(r) - lesson := strings.TrimPrefix(r.URL.Path, "/lesson/") - if err := writeLesson(lesson, w); err != nil { - if err == lessonNotFound { - http.NotFound(w, r) - } else { - c.Criticalf("tour render: %v", err) - } + registerStatic(".") + + port := os.Getenv("PORT") + if port == "" { + port = "8080" } + log.Fatal(http.ListenAndServe(":"+port, nil)) } -// prepContent returns a Reader that produces the content from the given +// gaePrepContent returns a Reader that produces the content from the given // Reader, but strips the prefix "#appengine: " from each line. It also drops // any non-blank like that follows a series of 1 or more lines with the prefix. -func prepContent(in io.Reader) io.Reader { +func gaePrepContent(in io.Reader) io.Reader { var prefix = []byte("#appengine: ") out, w := io.Pipe() go func() { @@ -84,9 +71,9 @@ func prepContent(in io.Reader) io.Reader { return out } -// socketAddr returns the WebSocket handler address. +// gaeSocketAddr returns the WebSocket handler address. // The App Engine version does not provide a WebSocket handler. -func socketAddr() string { return "" } +func gaeSocketAddr() string { return "" } // hstsHandler wraps an http.HandlerFunc such that it sets the HSTS header. func hstsHandler(fn http.HandlerFunc) http.Handler { @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !appengine - package main import ( @@ -31,7 +29,7 @@ import ( ) const ( - basePkg = "golang.org/x/tour/" + basePkg = "golang.org/x/tour" socketPath = "/socket" ) @@ -76,6 +74,12 @@ func findRoot() (string, error) { func main() { flag.Parse() + if os.Getenv("GAE_ENV") == "standard" { + log.Println("running in App Engine Standard mode") + gaeMain() + return + } + // find and serve the go tour files root, err := findRoot() if err != nil { @@ -106,12 +110,7 @@ func main() { origin := &url.URL{Scheme: "http", Host: host + ":" + port} http.Handle(socketPath, socket.NewHandler(origin)) - // Keep these static file handlers in sync with app.yaml. - static := http.FileServer(http.Dir(root)) - http.Handle("/content/img/", static) - http.Handle("/static/", static) - imgDir := filepath.Join(root, "static", "img") - http.Handle("/favicon.ico", http.FileServer(http.Dir(imgDir))) + registerStatic(root) go func() { url := "http://" + httpAddr @@ -124,6 +123,16 @@ func main() { log.Fatal(http.ListenAndServe(httpAddr, nil)) } +// registerStatic registers handlers to serve static content +// from the directory root. +func registerStatic(root string) { + // Keep these static file handlers in sync with app.yaml. + http.Handle("/favicon.ico", http.FileServer(http.Dir(filepath.Join(root, "static", "img")))) + static := http.FileServer(http.Dir(root)) + http.Handle("/content/img/", static) + http.Handle("/static/", static) +} + // rootHandler returns a handler for all the requests except the ones for lessons. func rootHandler(w http.ResponseWriter, r *http.Request) { if err := renderUI(w); err != nil { @@ -146,7 +155,8 @@ func lessonHandler(w http.ResponseWriter, r *http.Request) { const localhostWarning = ` WARNING! WARNING! WARNING! -I appear to be listening on an address that is not localhost. +The tour server appears to be listening on an address that is +not localhost and is configured to run code snippets locally. Anyone with access to this address and port will have access to this machine as the user running gotour. @@ -210,7 +220,7 @@ func startBrowser(url string) bool { } // prepContent for the local tour simply returns the content as-is. -func prepContent(r io.Reader) io.Reader { return r } +var prepContent = func(r io.Reader) io.Reader { return r } // socketAddr returns the WebSocket handler address. -func socketAddr() string { return "ws://" + httpAddr + socketPath } +var socketAddr = func() string { return "ws://" + httpAddr + socketPath } |
