package main import ( "fmt" "log" "net/http" "os" "path" "time" "github.com/google/uuid" "golang.org/x/time/rate" ) type Server struct { fs http.Handler ws *WS limiter *rate.Limiter uuid string } func New() *Server { fs := http.FileServer(http.Dir(config().GetString("d"))) return &Server{ fs: fs, ws: NewWS(), limiter: rate.NewLimiter(rate.Every(time.Second), 2), uuid: uuid.New().String(), } } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !s.Authorize(w, r) { return } log.Println("ext", path.Ext(r.URL.Path)) if path.Ext(r.URL.Path) != "" { s.fs.ServeHTTP(w, r) } else if _, err := os.Stat(path.Join(config().GetString("d"), r.URL.Path[1:])); os.IsNotExist(err) { s.ws.ServeHTTP(w, r) } else { s.fs.ServeHTTP(w, r) } } func (s *Server) Authorize(w http.ResponseWriter, r *http.Request) bool { if u, p, ok := r.BasicAuth(); !ok || u != "Q" || p != "Q" { s.limiter.Wait(r.Context()) w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", r.Host)) w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized")) return false } return true }