package handlers import ( "git.haelnorr.com/h/golib/hws" "net/http" "path/filepath" "strings" ) // Handles requests for static files, without allowing access to the // directory viewer and returning 404 if an exact file is not found func StaticFS(staticFS *http.FileSystem, server *hws.Server) http.Handler { // Create the file server once, not on every request fs, err := hws.SafeFileServer(staticFS) if err != nil { // If we can't create the file server, return a handler that always errors return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { throwInternalServiceError(server, w, r, "An error occurred trying to load the file system", err) }) } return http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { // Explicitly set Content-Type for CSS files if strings.HasSuffix(r.URL.Path, ".css") { w.Header().Set("Content-Type", "text/css; charset=utf-8") } else if strings.HasSuffix(r.URL.Path, ".js") { w.Header().Set("Content-Type", "application/javascript; charset=utf-8") } else if strings.HasSuffix(r.URL.Path, ".ico") { w.Header().Set("Content-Type", "image/x-icon") } else { // Let Go detect the content type for other files ext := filepath.Ext(r.URL.Path) if contentType := mimeTypes[ext]; contentType != "" { w.Header().Set("Content-Type", contentType) } } fs.ServeHTTP(w, r) }, ) } // Common MIME types for static files var mimeTypes = map[string]string{ ".html": "text/html; charset=utf-8", ".css": "text/css; charset=utf-8", ".js": "application/javascript; charset=utf-8", ".json": "application/json; charset=utf-8", ".xml": "application/xml; charset=utf-8", ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".svg": "image/svg+xml", ".ico": "image/x-icon", ".webp": "image/webp", ".woff": "font/woff", ".woff2": "font/woff2", ".ttf": "font/ttf", ".eot": "application/vnd.ms-fontobject", }