service/main.go (72 lines of code) (raw):

package main import ( "bytes" "fmt" "log" "net/http" "os" "path" "time" "github.com/guardian/actions-static-site/service/middleware" "github.com/guardian/actions-static-site/service/s3" "github.com/guardian/actions-static-site/service/store" ) type Config struct { Port, Bucket string // Override when local for easier testing. RequireAuth bool Profile string } func required(key string) string { got := os.Getenv(key) if got == "" { log.Fatalf("required env var %s is missing", key) } return got } func optional(key, fallback string) string { got := os.Getenv(key) if got == "" { return fallback } return got } func getConfig() Config { return Config{ Bucket: required("BUCKET"), Port: optional("PORT", "3333"), RequireAuth: optional("REQUIRE_AUTH", "true") != "false", Profile: optional("PROFILE", ""), } } func main() { config := getConfig() store := s3.New(config.Bucket, config.Profile) http.HandleFunc("/healthcheck", middleware.WithRequestLog(http.HandlerFunc(ok))) if config.RequireAuth { http.Handle("/", middleware.WithRequestLog(middleware.WithAuth(middleware.WithDomainPrefix(storeServer(store))))) } else { http.Handle("/", middleware.WithRequestLog(middleware.WithDomainPrefix(storeServer(store)))) } log.Printf("Server starting on http://localhost:%s.", config.Port) err := http.ListenAndServe(fmt.Sprintf(":%s", config.Port), nil) log.Fatal(err.Error()) } func ok(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "OK") } func storeServer(store store.Store) http.HandlerFunc { return func(resp http.ResponseWriter, req *http.Request) { key := req.URL.Path got, err := store.Get(key) if err != nil { log.Printf("unable to fetch from store for path %s and host %s: %v", req.URL.Path, req.Host, err) statusNotFound(resp) } _, name := path.Split(key) http.ServeContent(resp, req, name, time.Time{}, bytes.NewReader(got)) } } func statusNotFound(w http.ResponseWriter) { w.WriteHeader(http.StatusNotFound) fmt.Fprintln(w, "Status Not Found (404) - resource not found.") }