|
|
@ -4,11 +4,14 @@ import ( |
|
|
|
"compress/flate" |
|
|
|
"flag" |
|
|
|
"fmt" |
|
|
|
"log" |
|
|
|
"net/http" |
|
|
|
"os" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
|
|
|
|
"git.coolaj86.com/coolaj86/goserv/assets" |
|
|
|
"git.coolaj86.com/coolaj86/goserv/internal/db" |
|
|
|
|
|
|
|
"github.com/go-chi/chi" |
|
|
|
"github.com/go-chi/chi/middleware" |
|
|
@ -45,6 +48,7 @@ type runOptions struct { |
|
|
|
var runFlags *flag.FlagSet |
|
|
|
var runOpts runOptions |
|
|
|
var initFlags *flag.FlagSet |
|
|
|
var dbURL string |
|
|
|
|
|
|
|
func init() { |
|
|
|
runOpts = runOptions{} |
|
|
@ -53,6 +57,12 @@ func init() { |
|
|
|
runFlags.BoolVar(&runOpts.trustProxy, "trust-proxy", false, "trust X-Forwarded-For header") |
|
|
|
runFlags.BoolVar(&runOpts.compress, "compress", true, "enable compression for text,html,js,css,etc") |
|
|
|
runFlags.StringVar(&runOpts.static, "serve-path", "", "path to serve, falls back to built-in web app") |
|
|
|
runFlags.StringVar( |
|
|
|
&dbURL, |
|
|
|
"db-url", |
|
|
|
"postgres://postgres:postgres@localhost:5432/postgres", |
|
|
|
"database (postgres) connection url", |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
func main() { |
|
|
@ -92,9 +102,12 @@ func main() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var startedAt = time.Now() |
|
|
|
var defaultMaxBytes int64 = 1 << 20 |
|
|
|
|
|
|
|
func serve() { |
|
|
|
initDB(dbURL) |
|
|
|
|
|
|
|
r := chi.NewRouter() |
|
|
|
|
|
|
|
// A good base middleware stack
|
|
|
@ -109,6 +122,25 @@ func serve() { |
|
|
|
|
|
|
|
r.Route("/api", func(r chi.Router) { |
|
|
|
r.Use(limitResponseSize) |
|
|
|
r.Use(jsonAllTheThings) |
|
|
|
|
|
|
|
r.Route("/public", func(r chi.Router) { |
|
|
|
r.Get("/status", func(w http.ResponseWriter, r *http.Request) { |
|
|
|
w.Write([]byte(fmt.Sprintf( |
|
|
|
`{ "success": true, "uptime": %.0f }%s`, |
|
|
|
time.Since(startedAt).Seconds(), |
|
|
|
"\n", |
|
|
|
))) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
r.Route("/user", func(r chi.Router) { |
|
|
|
r.Get("/inspect", func(w http.ResponseWriter, r *http.Request) { |
|
|
|
w.Write([]byte(fmt.Sprintf( |
|
|
|
`{ "success": false, "error": "not implemented" }%s`, "\n", |
|
|
|
))) |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
var staticHandler http.HandlerFunc |
|
|
@ -149,9 +181,35 @@ func serve() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func jsonAllTheThings(next http.Handler) http.Handler { |
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
|
|
// just setting a default, other handlers can change this
|
|
|
|
w.Header().Set("Content-Type", "application/json") |
|
|
|
next.ServeHTTP(w, r) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
func limitResponseSize(next http.Handler) http.Handler { |
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
|
|
r.Body = http.MaxBytesReader(w, r.Body, defaultMaxBytes) |
|
|
|
next.ServeHTTP(w, r) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
func initDB(connStr string) { |
|
|
|
// TODO url.Parse
|
|
|
|
if strings.Contains(connStr, "@localhost/") || strings.Contains(connStr, "@localhost:") { |
|
|
|
connStr += "?sslmode=disable" |
|
|
|
} else { |
|
|
|
connStr += "?sslmode=required" |
|
|
|
} |
|
|
|
|
|
|
|
err := db.Init(connStr) |
|
|
|
if nil != err { |
|
|
|
log.Println("db connection error", err) |
|
|
|
//log.Fatal("db connection error", err)
|
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
return |
|
|
|
} |
|
|
|