76 lines
1.5 KiB
Go
76 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
|
|
"golang.org/x/time/rate"
|
|
)
|
|
|
|
type S struct {
|
|
ctx context.Context
|
|
limiter *rate.Limiter
|
|
config Config
|
|
}
|
|
|
|
func (s *S) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if err := s.serveHTTP(w, r); err != nil {
|
|
log.Println(s.Session(r.Context()), "//", r.URL.Path, "//", err.Error())
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func (s *S) serveHTTP(w http.ResponseWriter, r *http.Request) error {
|
|
if isV1(r) || isWS(r) {
|
|
return s.serveAPI(w, r)
|
|
}
|
|
return s.serveStatic(w, r)
|
|
}
|
|
|
|
func (s *S) serveStatic(w http.ResponseWriter, r *http.Request) error {
|
|
http.FS(http.Dir(s.config.Root)).ServeHTTP(w, r)
|
|
return nil
|
|
}
|
|
|
|
func (s *S) serveAPI(w http.ResponseWriter, r *http.Request) error {
|
|
if err := s.injectContext(w, r); err == io.EOF {
|
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
|
return nil
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
|
|
if isWS(r) {
|
|
return s.serveWS(w, r)
|
|
} else if isV1(r) {
|
|
return s.serveV1(w, r)
|
|
}
|
|
|
|
http.NotFound(w, r)
|
|
return nil
|
|
}
|
|
|
|
type Session struct {
|
|
ID string
|
|
}
|
|
|
|
func (s *S) injectContext(w http.ResponseWriter, r *http.Request) error {
|
|
id, err := r.Cookie("uuid")
|
|
if err != nil || id.Value == "" {
|
|
return io.EOF
|
|
}
|
|
ctx := r.Context()
|
|
ctx = context.WithValue(ctx, "session", Session{
|
|
ID: id.Value,
|
|
})
|
|
*r = *r.WithContext(ctx)
|
|
return nil
|
|
}
|
|
|
|
func (s *S) Session(ctx context.Context) Session {
|
|
v, _ := ctx.Value("session").(Session)
|
|
return v
|
|
}
|