(w http.ResponseWriter, r *http.Request)
| 60 | } |
| 61 | |
| 62 | func (s *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 63 | pathname := r.URL.Path |
| 64 | switch pathname { |
| 65 | case "/@hmr", "/@refresh", "/@prefresh", "/@vdr": |
| 66 | s.ServeInternalJS(w, r, pathname[2:]) |
| 67 | case "/@hmr-ws": |
| 68 | if s.watchData == nil { |
| 69 | s.watchData = make(map[*websocket.Conn]map[string]int64) |
| 70 | go s.watchFS() |
| 71 | } |
| 72 | s.ServeHmrWS(w, r) |
| 73 | default: |
| 74 | filename := filepath.Join(s.config.AppDir, pathname) |
| 75 | fi, err := os.Lstat(filename) |
| 76 | if err == nil && fi.IsDir() { |
| 77 | if pathname != "/" && !strings.HasSuffix(pathname, "/") { |
| 78 | http.Redirect(w, r, pathname+"/", http.StatusMovedPermanently) |
| 79 | return |
| 80 | } |
| 81 | pathname = strings.TrimSuffix(pathname, "/") + "/index.html" |
| 82 | filename = filepath.Join(s.config.AppDir, pathname) |
| 83 | fi, err = os.Lstat(filename) |
| 84 | } |
| 85 | if err != nil && os.IsNotExist(err) { |
| 86 | if s.config.Fallback != "" { |
| 87 | pathname = "/" + strings.TrimPrefix(s.config.Fallback, "/") |
| 88 | filename = filepath.Join(s.config.AppDir, pathname) |
| 89 | fi, err = os.Lstat(filename) |
| 90 | } else { |
| 91 | pathname = "/404.html" |
| 92 | filename = filepath.Join(s.config.AppDir, pathname) |
| 93 | fi, err = os.Lstat(filename) |
| 94 | if err != nil && os.IsNotExist(err) { |
| 95 | pathname = "/index.html" |
| 96 | filename = filepath.Join(s.config.AppDir, pathname) |
| 97 | fi, err = os.Lstat(filename) |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | if err != nil { |
| 102 | if os.IsNotExist(err) { |
| 103 | http.Error(w, "Not Found", 404) |
| 104 | } else { |
| 105 | http.Error(w, "Internal Server Error", 500) |
| 106 | } |
| 107 | return |
| 108 | } |
| 109 | if fi.IsDir() { |
| 110 | http.Error(w, "Forbidden", http.StatusForbidden) |
| 111 | return |
| 112 | } |
| 113 | query := r.URL.Query() |
| 114 | if query.Has("url") { |
| 115 | header := w.Header() |
| 116 | header.Set("Content-Type", "application/javascript; charset=utf-8") |
| 117 | header.Set("Cache-Control", "public, max-age=31536000, immutable") |
| 118 | w.Write([]byte(`const url = new URL(import.meta.url);url.searchParams.delete("url");export default url.href;`)) |
| 119 | return |
nothing calls this directly
no test coverage detected