Discover books, shows, and movies at your level. Track your progress by filling your Shelf with what you find, and share with other language learners. *No dusting required.
shlf.space
1package server
2
3import (
4 "net/http"
5 "strings"
6
7 "github.com/go-chi/chi/v5"
8 "shlf.space/internal/atproto"
9 "shlf.space/internal/server/middleware"
10 notfound "shlf.space/internal/views/not-found"
11)
12
13func (s *Server) Router() http.Handler {
14 router := chi.NewRouter()
15 middleware := middleware.New(
16 s.oauth,
17 s.idResolver,
18 )
19
20 userRouter := s.UserRouter(&middleware)
21 standardRouter := s.StandardRouter(&middleware)
22
23 router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) {
24 pat := chi.URLParam(r, "*")
25 pathParts := strings.SplitN(pat, "/", 2)
26
27 if len(pathParts) > 0 {
28 firstPart := pathParts[0]
29
30 // if using a DID or handle, just continue as per usual
31 if atproto.IsDid(firstPart) || atproto.IsHandle(firstPart) {
32 userRouter.ServeHTTP(w, r)
33 return
34 }
35
36 // if using a handle with @, rewrite to work without @
37 if normalized := strings.TrimPrefix(firstPart, "@"); atproto.IsHandle(normalized) {
38 redirectPath := strings.Join(append([]string{normalized}, pathParts[1:]...), "/")
39
40 redirectURL := *r.URL
41 redirectURL.Path = "/" + redirectPath
42
43 http.Redirect(w, r, redirectURL.String(), http.StatusFound)
44 return
45 }
46
47 }
48
49 standardRouter.ServeHTTP(w, r)
50 })
51
52 return router
53}
54
55func (s *Server) StandardRouter(middleware *middleware.Middleware) http.Handler {
56 router := chi.NewRouter()
57
58 router.Handle("/static/*", s.HandleStatic())
59
60 router.Get("/", s.Index)
61
62 router.Get("/login", s.Login)
63 router.Post("/login", s.Login)
64 router.Post("/logout", s.Logout)
65
66 router.Mount("/", s.oauth.Router())
67
68 return router
69}
70
71func (s *Server) UserRouter(middleware *middleware.Middleware) http.Handler {
72 router := chi.NewRouter()
73
74 router.With(middleware.ResolveIdent()).Route("/{user}", func(r chi.Router) {
75 r.Get("/books", s.MyBooks)
76 })
77
78 router.NotFound(func(w http.ResponseWriter, r *http.Request) {
79 w.WriteHeader(http.StatusNotFound)
80 notfound.NotFoundPage(notfound.NotFoundParams{}).Render(r.Context(), w)
81 })
82
83 return router
84}