62 lines
1.3 KiB
Go
Executable File
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
|
|
}
|