commit 35dcbf8b75e53f920da4194ee153ffca0e5ccd22
parent 1f929fc4f22df70b2ddd814cc17474e40cab92f3
Author: Ryan Wolf <johnwayne@pseudony.ms>
Date: Sun, 17 Feb 2019 09:50:13 -0500
Update for 7 years of changes to app engine
* Application name, version no longer required.
* gcloud app deploy looks for any main in the dir, doesn't need to be in a
subdir.
Diffstat:
4 files changed, 81 insertions(+), 91 deletions(-)
diff --git a/README.md b/README.md
@@ -4,7 +4,6 @@ Setup
1. Get your [dev environment](https://developers.google.com/appengine/docs/go/gettingstarted/devenvironment) setup for GAE.
2. Clone this repository, cd into the directory.
3. ```cp app.yaml.example app.yaml```
-4. Edit app.yaml with the app name you plan to use.
Running locally
===
@@ -19,21 +18,14 @@ password for changing the answer is "bees".
To change the answer to "no", simply visit larry:bees@localhost:8080/no
-Running tests
-===
-
-1. Install go.
-2. ```$ cd basicauth/ && go test```
-
Running on appspot
===
1. Follow the [registration instuctions](https://developers.google.com/appengine/docs/go/gettingstarted/uploading) for GAE.
-2. Make sure that the app id in app.yaml matches you new app id.
-3. Push the app: ```$ appcfg.py .```
-4. Seed the server with starting data. I'd suggest a different password than
+2. Push the app: ```$ appcfg.py .```
+3. Seed the server with starting data. I'd suggest a different password than
"bees": ```$ curl http://moe:$PASSWORD@$APPID.appspot.com/yes```
-5. Visit $APPID.appspot.com in your browser to behold your new novelty server.
+4. Visit $APPID.appspot.com in your browser to behold your new novelty server.
Sample Benchmarks
===
diff --git a/app.yaml.example b/app.yaml.example
@@ -1,5 +1,3 @@
-application: novelty
-version: 3
runtime: go
api_version: go1
diff --git a/novelty.go b/novelty.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+ "appengine"
+ "appengine/datastore"
+ "html/template"
+ "net/http"
+)
+
+type Answer struct {
+ Value string
+}
+
+type Password struct {
+ Value string
+}
+
+func init() {
+ http.HandleFunc("/", getAnswer)
+ http.HandleFunc("/yes", setAnswer("yes"))
+ http.HandleFunc("/no", setAnswer("no"))
+}
+
+func getAnswer(w http.ResponseWriter, r *http.Request) {
+ c := appengine.NewContext(r)
+ k := datastore.NewKey(c, "Answer", "answer", 0, nil)
+ a := new(Answer)
+ if err := datastore.Get(c, k, a); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ t := template.Must(template.ParseFiles("index.template"))
+ if err := t.Execute(w, a); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+}
+
+func authorized(r *http.Request) bool {
+ _, password, ok := r.BasicAuth()
+ if !ok {
+ return false
+ }
+ c := appengine.NewContext(r)
+ k := datastore.NewKey(c, "Password", "password", 0, nil)
+ p := new(Password)
+ if err := datastore.Get(c, k, p); err != nil {
+ // If password is not set, seed with whatever password was passed in.
+ // See: http://golang.org/misc/dashboard/app/build/key.go
+ dp := Password{
+ Value: password,
+ }
+ if _, err := datastore.Put(c, k, &dp); err != nil {
+ return false
+ }
+ return true
+ }
+ return p.Value == password
+}
+
+func setAnswer(answer string) func(w http.ResponseWriter, r *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if !authorized(r) {
+ w.Header().Set("WWW-Authenticate", "Basic realm=\"novelty.go\"")
+ http.Error(w, "Unauthorized", http.StatusUnauthorized)
+ return
+ }
+ c := appengine.NewContext(r)
+ k := datastore.NewKey(c, "Answer", "answer", 0, nil)
+ a := Answer{
+ Value: answer,
+ }
+ if _, err := datastore.Put(c, k, &a); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ http.Redirect(w, r, "/", http.StatusFound)
+ }
+}
diff --git a/novelty/novelty.go b/novelty/novelty.go
@@ -1,78 +0,0 @@
-package novelty
-
-import (
- "appengine"
- "appengine/datastore"
- "html/template"
- "net/http"
-)
-
-type Answer struct {
- Value string
-}
-
-type Password struct {
- Value string
-}
-
-func init() {
- http.HandleFunc("/", getAnswer)
- http.HandleFunc("/yes", setAnswer("yes"))
- http.HandleFunc("/no", setAnswer("no"))
-}
-
-func getAnswer(w http.ResponseWriter, r *http.Request) {
- c := appengine.NewContext(r)
- k := datastore.NewKey(c, "Answer", "answer", 0, nil)
- a := new(Answer)
- if err := datastore.Get(c, k, a); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- t := template.Must(template.ParseFiles("index.template"))
- if err := t.Execute(w, a); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- }
-}
-
-func authorized(r *http.Request) bool {
- _, password, ok := r.BasicAuth()
- if !ok {
- return false
- }
- c := appengine.NewContext(r)
- k := datastore.NewKey(c, "Password", "password", 0, nil)
- p := new(Password)
- if err := datastore.Get(c, k, p); err != nil {
- // If password is not set, seed with whatever password was passed in.
- // See: http://golang.org/misc/dashboard/app/build/key.go
- dp := Password{
- Value: password,
- }
- if _, err := datastore.Put(c, k, &dp); err != nil {
- return false
- }
- return true
- }
- return p.Value == password
-}
-
-func setAnswer(answer string) func(w http.ResponseWriter, r *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- if !authorized(r) {
- w.Header().Set("WWW-Authenticate", "Basic realm=\"novelty.go\"")
- http.Error(w, "Unauthorized", http.StatusUnauthorized)
- return
- }
- c := appengine.NewContext(r)
- k := datastore.NewKey(c, "Answer", "answer", 0, nil)
- a := Answer{
- Value: answer,
- }
- if _, err := datastore.Put(c, k, &a); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- http.Redirect(w, r, "/", http.StatusFound)
- }
-}