converge/cmd/converge/fileserver.go
2024-09-08 11:16:48 +02:00

68 lines
1.6 KiB
Go

package main
import (
"html/template"
"net/http"
"os"
"path/filepath"
"strings"
)
type FileHandlerFilter struct {
dir string
fileHandler http.Handler
}
func NewFileHandler(dir string) *FileHandlerFilter {
handler := FileHandlerFilter{
dir: dir,
fileHandler: http.FileServer(http.Dir(dir)),
}
return &handler
}
func (handler FileHandlerFilter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
contextPath := r.URL.Path
path := filepath.Join(handler.dir, contextPath)
fileInfo, err := os.Stat(path)
if err == nil && fileInfo.IsDir() {
contextPath = filepath.Join(contextPath, "index.html")
}
if !strings.HasSuffix(contextPath, ".html") {
handler.fileHandler.ServeHTTP(w, r)
return
}
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "0")
filters := make(map[string]string)
if r.TLS == nil {
filters["secure"] = ""
} else {
filters["secure"] = "s"
}
for _, header := range []string{"X-Forwarded-Proto", "X-Scheme", "X-Forwarded-Scheme"} {
values := r.Header.Values(header)
for _, value := range values {
if strings.ToLower(value) == "https" {
filters["secure"] = "s"
}
}
}
filters["host"] = r.Host
tmpl, err := template.ParseFiles(filepath.Join(handler.dir, contextPath))
if err != nil {
// let the filehandler generate the rror
handler.fileHandler.ServeHTTP(w, r)
}
err = tmpl.Execute(w, filters)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
// ok, tmpl has written the response
}