pkg/main.go
Alexander Kiryukhin cc3ae00bbb
initial
2022-03-24 23:25:02 +03:00

113 lines
2.5 KiB
Go

package main
import (
"context"
"encoding/json"
"html/template"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
var (
templates = template.Must(template.ParseGlob("./tpl/*.gohtml"))
packages = Packages{}
)
func main() {
addr := os.Getenv("ADDR")
if addr == "" {
addr = ":8080"
}
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()
cfg := &Config{}
fp, err := os.Open("./config.json")
if err != nil {
log.Fatal(err)
}
if err := json.NewDecoder(fp).Decode(cfg); err != nil {
log.Fatal(err)
}
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.StripSlashes)
r.Use(middleware.RealIP)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
templates.ExecuteTemplate(w, "index.gohtml", indexRenderContext{
Title: cfg.Title,
Packages: cfg.Packages,
Host: cfg.Host,
Doc: "//pkg.go.dev/",
})
})
r.Get("/{pkg}", func(w http.ResponseWriter, r *http.Request) {
pkgID := chi.URLParam(r, "pkg")
pkg, ok := (*cfg.Packages)[pkgID]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
w.WriteHeader(http.StatusOK)
templates.ExecuteTemplate(w, "package.gohtml", pageRenderContext{
Title: cfg.Title,
Package: &pkg,
Host: cfg.Host,
Doc: "//pkg.go.dev/",
})
})
workDir, _ := os.Getwd()
filesDir := http.Dir(filepath.Join(workDir, "static"))
FileServer(r, "/static", filesDir)
srv := &http.Server{
Handler: r,
Addr: addr,
}
go func() {
<-ctx.Done()
srv.Shutdown(context.Background())
}()
log.Println("Start at", addr)
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatal(err)
}
}
// FileServer conveniently sets up a http.FileServer handler to serve
// static files from a http.FileSystem.
func FileServer(r chi.Router, path string, root http.FileSystem) {
if strings.ContainsAny(path, "{}*") {
panic("FileServer does not permit any URL parameters.")
}
if path != "/" && path[len(path)-1] != '/' {
r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP)
path += "/"
}
path += "*"
r.Get(path, func(w http.ResponseWriter, r *http.Request) {
rctx := chi.RouteContext(r.Context())
pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*")
fs := http.StripPrefix(pathPrefix, http.FileServer(root))
fs.ServeHTTP(w, r)
})
}