package httputils import ( "bytes" "fmt" "net/http" "os" "path/filepath" "reflect" "strings" "time" ) type Handler = func(http.ResponseWriter, *http.Request) func getPartials() ([]string, map[string]time.Time, error) { var modTimes map[string]time.Time = make(map[string]time.Time) err := filepath.Walk(partialsFolder, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.IsDir() && strings.HasSuffix(path, ".html") { modTimes[path] = info.ModTime() } return nil }) paths := make([]string, len(modTimes)) i := 0 for path := range modTimes { paths[i] = path i++ } return paths, modTimes, err } const reloadTemplates = true func GenerateHandler( handler func(http.ResponseWriter, *http.Request) bool, templateSet TemplateSet, template func(http.ResponseWriter, *http.Request) (template string, data any), methods []string, ) Handler { return func(w http.ResponseWriter, r *http.Request) { for _, method := range methods { if method == r.Method { goto ok } } w.WriteHeader(http.StatusMethodNotAllowed) return ok: renderTemplate := handler(w, r) if renderTemplate { file_path, data := template(w, r) buf := &bytes.Buffer{} err := templateSet.ExecuteTemplate(buf, file_path, reflect.ValueOf(data)) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w, "500 Internal Server Error") return } w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprint(w, buf.String()) } } } func GenerateSseHandler(handler Handler) Handler { return func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { w.WriteHeader(http.StatusMethodNotAllowed) return } w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") w.WriteHeader(http.StatusOK) handler(w, r) } }