An experimental IndieWeb site built in Go.
at main 2.2 kB view raw
1package main 2 3//go:generate templ generate 4//go:generate deno run --allow-all npm:tailwindcss -i config/main.css -o static/styles.css -c config/tailwind.config.ts --minify 5 6import ( 7 "os" 8 "time" 9 10 "log" 11 "net/http" 12 "strconv" 13 14 "github.com/puregarlic/space/handlers" 15 "github.com/puregarlic/space/models" 16 "github.com/puregarlic/space/storage" 17 18 "github.com/go-chi/chi/v5" 19 "github.com/go-chi/chi/v5/middleware" 20 "github.com/go-chi/cors" 21 "github.com/go-chi/httprate" 22 23 "go.hacdias.com/indielib/indieauth" 24 25 _ "github.com/joho/godotenv/autoload" 26) 27 28func main() { 29 port, profileURL := validateRuntimeConfiguration() 30 defer storage.CleanupCaches() 31 32 storage.GORM().AutoMigrate(&models.Post{}) 33 34 r := chi.NewRouter() 35 36 r.Use(middleware.RequestID) 37 r.Use(middleware.RealIP) 38 r.Use(middleware.Logger) 39 r.Use(middleware.Recoverer) 40 r.Use(httprate.LimitByIP(100, 1*time.Minute)) 41 42 // CORS be enabled for browser-based agents to fetch `rel` elements. 43 // We'll enable it just on the root route since it should be used as the profile URL 44 r.With(cors.AllowAll().Handler).Get("/", handlers.ServeHomePage) 45 46 // Content pages 47 r.Get("/posts/{slug}", handlers.ServePostPage) 48 49 // Static asset handlers 50 r.Get("/media/*", handlers.ServeMedia) 51 r.Get("/static/*", http.StripPrefix( 52 "/static", 53 http.FileServer(http.Dir("static")), 54 ).ServeHTTP) 55 56 // Service handlers 57 handlers.AttachIndieAuth(r, "/authorization", profileURL) 58 handlers.AttachMicropub(r, "/micropub", profileURL) 59 60 // Start it! 61 log.Printf("Listening on http://localhost:%d", port) 62 log.Printf("Listening on %s", profileURL) 63 if err := http.ListenAndServe(":"+strconv.Itoa(port), r); err != nil { 64 log.Fatal(err) 65 } 66} 67 68func validateRuntimeConfiguration() (portNumber int, profileURL string) { 69 var port int 70 if portStr, ok := os.LookupEnv("PORT"); !ok { 71 port = 80 72 } else { 73 portInt, err := strconv.Atoi(portStr) 74 if err != nil { 75 log.Fatal(err) 76 } 77 78 port = portInt 79 } 80 81 profileURL, ok := os.LookupEnv("PROFILE_URL") 82 if !ok { 83 profileURL = "http://localhost/" 84 } 85 86 // Validate the given Client ID before starting the HTTP server. 87 err := indieauth.IsValidProfileURL(profileURL) 88 if err != nil { 89 log.Fatal(err) 90 } 91 92 return port, profileURL 93}