From beec45c87627ad55ba5524913750c4a044c9270b Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 18 Jan 2024 23:00:13 -0600 Subject: [PATCH] refactor: move repo to middleware/context Signed-off-by: jolheiser --- internal/http/http.go | 4 +++ internal/http/middleware.go | 36 +++++++++++++++++++ internal/http/repo.go | 69 ++++--------------------------------- 3 files changed, 47 insertions(+), 62 deletions(-) create mode 100644 internal/http/middleware.go diff --git a/internal/http/http.go b/internal/http/http.go index 7e1bf4a..3fc9b6d 100644 --- a/internal/http/http.go +++ b/internal/http/http.go @@ -62,6 +62,9 @@ func New(settings Settings) Server { rh := repoHandler{s: settings} mux.Route("/{repo}.git", func(r chi.Router) { + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/"+chi.URLParam(r, "repo"), http.StatusFound) + }) r.Get("/info/refs", httperr.Handler(rh.infoRefs)) r.Post("/git-upload-pack", httperr.Handler(rh.uploadPack)) }) @@ -69,6 +72,7 @@ func New(settings Settings) Server { mux.Route("/", func(r chi.Router) { r.Get("/", httperr.Handler(rh.index)) r.Route("/{repo}", func(r chi.Router) { + r.Use(rh.repoMiddleware) r.Get("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Has("go-get") { repo := chi.URLParam(r, "repo") diff --git a/internal/http/middleware.go b/internal/http/middleware.go new file mode 100644 index 0000000..90e3afc --- /dev/null +++ b/internal/http/middleware.go @@ -0,0 +1,36 @@ +package http + +import ( + "context" + "errors" + "io/fs" + "net/http" + + "github.com/go-chi/chi/v5" + "go.jolheiser.com/ugit/internal/git" + "go.jolheiser.com/ugit/internal/http/httperr" +) + +type ugitCtxKey string + +var repoCtxKey = ugitCtxKey("repo") + +func (rh repoHandler) repoMiddleware(next http.Handler) http.Handler { + return httperr.Handler(func(w http.ResponseWriter, r *http.Request) error { + repoName := chi.URLParam(r, "repo") + repo, err := git.NewRepo(rh.s.RepoDir, repoName) + if err != nil { + httpErr := http.StatusInternalServerError + if errors.Is(err, fs.ErrNotExist) { + httpErr = http.StatusNotFound + } + return httperr.Status(err, httpErr) + } + if repo.Meta.Private { + return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) + } + r = r.WithContext(context.WithValue(r.Context(), repoCtxKey, repo)) + next.ServeHTTP(w, r) + return nil + }) +} diff --git a/internal/http/repo.go b/internal/http/repo.go index bc0196e..2c4aa93 100644 --- a/internal/http/repo.go +++ b/internal/http/repo.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "go.jolheiser.com/ugit/internal/html/markup" - "io/fs" "mime" "net/http" "path/filepath" @@ -19,19 +18,9 @@ import ( func (rh repoHandler) repoTree(ref, path string) http.HandlerFunc { return httperr.Handler(func(w http.ResponseWriter, r *http.Request) error { - repoName := chi.URLParam(r, "repo") - repo, err := git.NewRepo(rh.s.RepoDir, repoName) - if err != nil { - httpErr := http.StatusInternalServerError - if errors.Is(err, fs.ErrNotExist) { - httpErr = http.StatusNotFound - } - return httperr.Status(err, httpErr) - } - if repo.Meta.Private { - return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) - } + repo := r.Context().Value(repoCtxKey).(*git.Repo) + var err error if ref == "" { ref, err = repo.DefaultBranch() if err != nil { @@ -61,7 +50,7 @@ func (rh repoHandler) repoTree(ref, path string) http.HandlerFunc { BaseContext: rh.baseContext(), RepoHeaderComponentContext: rh.repoHeaderContext(repo, r), RepoTreeComponentContext: html.RepoTreeComponentContext{ - Repo: repoName, + Repo: repo.Name(), Ref: ref, Tree: tree, Back: back, @@ -110,18 +99,7 @@ func (rh repoHandler) repoFile(w http.ResponseWriter, r *http.Request, repo *git } func (rh repoHandler) repoRefs(w http.ResponseWriter, r *http.Request) error { - repoName := chi.URLParam(r, "repo") - repo, err := git.NewRepo(rh.s.RepoDir, repoName) - if err != nil { - httpErr := http.StatusInternalServerError - if errors.Is(err, fs.ErrNotExist) { - httpErr = http.StatusNotFound - } - return httperr.Status(err, httpErr) - } - if repo.Meta.Private { - return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) - } + repo := r.Context().Value(repoCtxKey).(*git.Repo) branches, err := repo.Branches() if err != nil { @@ -146,18 +124,7 @@ func (rh repoHandler) repoRefs(w http.ResponseWriter, r *http.Request) error { } func (rh repoHandler) repoLog(w http.ResponseWriter, r *http.Request) error { - repoName := chi.URLParam(r, "repo") - repo, err := git.NewRepo(rh.s.RepoDir, repoName) - if err != nil { - httpErr := http.StatusInternalServerError - if errors.Is(err, fs.ErrNotExist) { - httpErr = http.StatusNotFound - } - return httperr.Status(err, httpErr) - } - if repo.Meta.Private { - return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) - } + repo := r.Context().Value(repoCtxKey).(*git.Repo) commits, err := repo.Commits(chi.URLParam(r, "ref")) if err != nil { @@ -176,18 +143,7 @@ func (rh repoHandler) repoLog(w http.ResponseWriter, r *http.Request) error { } func (rh repoHandler) repoCommit(w http.ResponseWriter, r *http.Request) error { - repoName := chi.URLParam(r, "repo") - repo, err := git.NewRepo(rh.s.RepoDir, repoName) - if err != nil { - httpErr := http.StatusInternalServerError - if errors.Is(err, fs.ErrNotExist) { - httpErr = http.StatusNotFound - } - return httperr.Status(err, httpErr) - } - if repo.Meta.Private { - return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) - } + repo := r.Context().Value(repoCtxKey).(*git.Repo) commit, err := repo.Commit(chi.URLParam(r, "commit")) if err != nil { @@ -214,18 +170,7 @@ func (rh repoHandler) repoCommit(w http.ResponseWriter, r *http.Request) error { } func (rh repoHandler) repoPatch(w http.ResponseWriter, r *http.Request) error { - repoName := chi.URLParam(r, "repo") - repo, err := git.NewRepo(rh.s.RepoDir, repoName) - if err != nil { - httpErr := http.StatusInternalServerError - if errors.Is(err, fs.ErrNotExist) { - httpErr = http.StatusNotFound - } - return httperr.Status(err, httpErr) - } - if repo.Meta.Private { - return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) - } + repo := r.Context().Value(repoCtxKey).(*git.Repo) commit, err := repo.Commit(chi.URLParam(r, "commit")) if err != nil {