package spa_handler import ( "embed" "fmt" "net/http" "os" "path" ) type handler struct { staticFS embed.FS indexPath string addLiveReloadScript bool clientVersion string } func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { reqPath := r.URL.Path lookupPath := path.Dir(h.indexPath) f, err := h.staticFS.Open(fmt.Sprintf("%s%s", lookupPath, reqPath)) if f != nil { f.Close() } if os.IsNotExist(err) { indexFile, indexErr := h.staticFS.Open(h.indexPath) if indexErr != nil { http.Error(w, "Index file not found", http.StatusInternalServerError) return } defer indexFile.Close() if h.addLiveReloadScript { tryToDeliverFile(indexFile, h.indexPath, w, r, clientScript(h.clientVersion)) } else { tryToDeliverFile(indexFile, h.indexPath, w, r) } return } else if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } tryToDeliverFile(f, h.indexPath, w, r) } func HandleFiles(path string, options HandlerOptions, mux *http.ServeMux) { if options.AdditionalMimeTypeMapping != nil { for key, value := range options.AdditionalMimeTypeMapping { contentTypeMapping[key] = value } } if mux == nil { http.Handle(path, handler{ staticFS: options.Files, indexPath: options.IndexPath, addLiveReloadScript: options.ActivateLiveReloading, clientVersion: options.ClientVersion, }) if options.ActivateLiveReloading { http.Handle("/_livereloader_", reloader{ clientVersion: options.ClientVersion, }) } return } else { mux.Handle(path, handler{ staticFS: options.Files, indexPath: options.IndexPath, }) if options.ActivateLiveReloading { mux.Handle("/_livereloader_", reloader{ clientVersion: options.ClientVersion, }) } } }