entropy/server.go

62 lines
1.3 KiB
Go
Executable File

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) {
log.Println("base", path.Base(r.URL.Path))
log.Println("dir", path.Dir(r.URL.Path))
if !s.Authorize(w, r) {
return
}
if path.Dir(r.URL.Path) == "/ws" {
s.ws.ServeHTTP(w, r)
} else {
r.URL.Path = "/" + path.Base(r.URL.Path)
if _, err := os.Stat(path.Join(config().GetString("d"), path.Base(r.URL.Path))); os.IsNotExist(err) {
r.URL.Path = "/"
s.fs.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
}