routes/git.go (view raw)
1package routes
2
3import (
4 "errors"
5 "log"
6 "net/http"
7 "path/filepath"
8
9 "github.com/go-git/go-billy/v5/osfs"
10 "github.com/go-git/go-git/v5/plumbing/format/pktline"
11 "github.com/go-git/go-git/v5/plumbing/protocol/packp"
12 "github.com/go-git/go-git/v5/plumbing/transport"
13 "github.com/go-git/go-git/v5/plumbing/transport/server"
14)
15
16func (d *deps) InfoRefs(w http.ResponseWriter, r *http.Request) {
17 name := r.PathValue("name")
18 name = filepath.Clean(name)
19
20 repo := filepath.Join(d.c.Repo.ScanPath, name)
21
22 w.Header().Set("content-type", "application/x-git-upload-pack-advertisement")
23
24 ep, err := transport.NewEndpoint("/")
25 if err != nil {
26 http.Error(w, err.Error(), 500)
27 log.Printf("git: %s", err)
28 return
29 }
30
31 billyfs := osfs.New(repo)
32 loader := server.NewFilesystemLoader(billyfs)
33 srv := server.NewServer(loader)
34 session, err := srv.NewUploadPackSession(ep, nil)
35 if err != nil {
36 http.Error(w, err.Error(), 500)
37 log.Printf("git: %s", err)
38 return
39 }
40
41 ar, err := session.AdvertisedReferencesContext(r.Context())
42 if errors.Is(err, transport.ErrRepositoryNotFound) {
43 http.Error(w, err.Error(), 404)
44 return
45 } else if err != nil {
46 http.Error(w, err.Error(), 500)
47 return
48 }
49
50 ar.Prefix = [][]byte{
51 []byte("# service=git-upload-pack"),
52 pktline.Flush,
53 }
54
55 if err = ar.Encode(w); err != nil {
56 http.Error(w, err.Error(), 500)
57 log.Printf("git: %s", err)
58 return
59 }
60}
61
62func (d *deps) UploadPack(w http.ResponseWriter, r *http.Request) {
63 name := r.PathValue("name")
64 name = filepath.Clean(name)
65
66 repo := filepath.Join(d.c.Repo.ScanPath, name)
67
68 w.Header().Set("content-type", "application/x-git-upload-pack-result")
69
70 upr := packp.NewUploadPackRequest()
71 err := upr.Decode(r.Body)
72 if err != nil {
73 http.Error(w, err.Error(), 400)
74 log.Printf("git: %s", err)
75 return
76 }
77
78 ep, err := transport.NewEndpoint("/")
79 if err != nil {
80 http.Error(w, err.Error(), 500)
81 log.Printf("git: %s", err)
82 return
83 }
84
85 billyfs := osfs.New(repo)
86 loader := server.NewFilesystemLoader(billyfs)
87 svr := server.NewServer(loader)
88 session, err := svr.NewUploadPackSession(ep, nil)
89 if err != nil {
90 http.Error(w, err.Error(), 500)
91 log.Printf("git: %s", err)
92 return
93 }
94
95 res, err := session.UploadPack(r.Context(), upr)
96 if err != nil {
97 http.Error(w, err.Error(), 500)
98 log.Printf("git: %s", err)
99 return
100 }
101
102 if err = res.Encode(w); err != nil {
103 http.Error(w, err.Error(), 500)
104 log.Printf("git: %s", err)
105 return
106 }
107}