6 files changed,
60 insertions(+),
26 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-01-21 01:49:14 +0200
Authored at:
2026-01-21 01:44:48 +0200
Change ID:
ytwpnunotkptnzqvoxsttzplswyrtqou
Parent:
3d9ab8a
M
internal/handlers/git.go
路路路 7 7 "net/http" 8 8 "path/filepath" 9 9 10 + "olexsmir.xyz/mugit/internal/git" 10 11 "olexsmir.xyz/mugit/internal/git/gitservice" 11 12 ) 12 13 14 +// multiplex, check if the request smells like gitprotocol-http(5), if so, it 15 +// passes it to git smart http, otherwise renders templates 16 +func (h *handlers) multiplex(w http.ResponseWriter, r *http.Request) { 17 + if r.URL.RawQuery == "service=git-receive-pack" { 18 + w.WriteHeader(http.StatusBadRequest) 19 + w.Write([]byte("http pushing isn't supported")) 20 + return 21 + } 22 + 23 + path := r.PathValue("rest") 24 + if path == "info/refs" && r.Method == "GET" && r.URL.RawQuery == "service=git-upload-pack" { 25 + h.infoRefs(w, r) 26 + } else if path == "git-upload-pack" && r.Method == "POST" { 27 + h.uploadPack(w, r) 28 + } else if r.Method == "GET" { 29 + h.repoIndex(w, r) 30 + } 31 +} 32 + 13 33 func (h *handlers) infoRefs(w http.ResponseWriter, r *http.Request) { 14 - // TODO: 404 for private repos 15 - 16 34 name := filepath.Clean(r.PathValue("name")) 35 + repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 36 + if err != nil { 37 + h.write404(w, err) 38 + return 39 + } 40 + 41 + isPrivate, err := repo.IsPrivate() 42 + if isPrivate || err != nil { 43 + h.write404(w, err) 44 + return 45 + } 17 46 18 47 w.Header().Set("content-type", "application/x-git-upload-pack-advertisement") 19 48 w.WriteHeader(http.StatusOK) 路路路 28 57 } 29 58 30 59 func (h *handlers) uploadPack(w http.ResponseWriter, r *http.Request) { 31 - // TODO: 404 for private repos 60 + name := filepath.Clean(r.PathValue("name")) 61 + repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 62 + if err != nil { 63 + h.write404(w, err) 64 + return 65 + } 32 66 33 - name := filepath.Clean(r.PathValue("name")) 67 + isPrivate, err := repo.IsPrivate() 68 + if isPrivate || err != nil { 69 + h.write404(w, err) 70 + return 71 + } 34 72 35 73 w.Header().Set("content-type", "application/x-git-upload-pack-result") 36 74 w.Header().Set("Connection", "Keep-Alive")
M
internal/handlers/handlers.go
路路路 39 39 return mux 40 40 } 41 41 42 -// multiplex, check if the request smells like gitprotocol-http(5), if so, it 43 -// passes it to git smart http, otherwise renders templates 44 -func (h *handlers) multiplex(w http.ResponseWriter, r *http.Request) { 45 - if r.URL.RawQuery == "service=git-receive-pack" { 46 - w.WriteHeader(http.StatusBadRequest) 47 - w.Write([]byte("http pushing isn't supported")) 48 - return 49 - } 50 - 51 - path := r.PathValue("rest") 52 - if path == "info/refs" && r.Method == "GET" && r.URL.RawQuery == "service=git-upload-pack" { 53 - h.infoRefs(w, r) 54 - } else if path == "git-upload-pack" && r.Method == "POST" { 55 - h.uploadPack(w, r) 56 - } else if r.Method == "GET" { 57 - h.repoIndex(w, r) 58 - } 59 -} 60 42 61 43 func (h *handlers) serveStatic(w http.ResponseWriter, r *http.Request) { 62 44 f := filepath.Clean(r.PathValue("file"))
M
internal/handlers/repo.go
路路路 54 54 continue 55 55 } 56 56 57 + if isPrivate, err := repo.IsPrivate(); err != nil || isPrivate { 58 + slog.Error("", "err", err) 59 + continue 60 + } 61 + 57 62 repoInfos = append(repoInfos, repoInfo{ 58 63 Name: name, 59 64 Desc: desc, 路路路 88 93 } 89 94 90 95 isPrivate, err := repo.IsPrivate() 91 - if isPrivate || err != nil { // FIX: private = 404, err = 500 96 + if isPrivate || err != nil { 92 97 h.write404(w, err) 93 98 return 94 99 }
M
internal/ssh/server.go
路路路 79 79 repoPath := cmd[1] 80 80 81 81 repoPath = filepath.Join(s.c.Repo.Dir, filepath.Clean(repoPath)) 82 - _, err := git.Open(repoPath, "") 82 + repo, err := git.Open(repoPath, "") 83 83 if err != nil { 84 84 slog.Error("ssh: failed to open repo", "err", err) 85 85 s.repoNotFound(sess) 路路路 88 88 89 89 switch gitCmd { 90 90 case "git-upload-pack": 91 + isPrivate, err := repo.IsPrivate() 92 + if err != nil { 93 + s.error(sess, err) 94 + return 95 + } 96 + 97 + if isPrivate && !authorized { 98 + s.repoNotFound(sess) 99 + return 100 + } 101 + 91 102 if err := gitservice.UploadPack(repoPath, false, sess, sess); err != nil { 92 103 s.error(sess, err) 93 104 return