web frontend for git (tangled's grandpa)
1package routes
2
3import (
4 "compress/gzip"
5 "io"
6 "log"
7 "net/http"
8 "path/filepath"
9
10 "git.icyphox.sh/legit/git/service"
11 securejoin "github.com/cyphar/filepath-securejoin"
12)
13
14func (d *deps) InfoRefs(w http.ResponseWriter, r *http.Request) {
15 name := r.PathValue("name")
16 name = filepath.Clean(name)
17
18 repo, err := securejoin.SecureJoin(d.c.Repo.ScanPath, name)
19 if err != nil {
20 log.Printf("securejoin error: %v", err)
21 d.Write404(w)
22 return
23 }
24
25 w.Header().Set("content-type", "application/x-git-upload-pack-advertisement")
26 w.WriteHeader(http.StatusOK)
27
28 cmd := service.ServiceCommand{
29 Dir: repo,
30 Stdout: w,
31 }
32
33 if err := cmd.InfoRefs(); err != nil {
34 http.Error(w, err.Error(), 500)
35 log.Printf("git: failed to execute git-upload-pack (info/refs) %s", err)
36 return
37 }
38}
39
40func (d *deps) UploadPack(w http.ResponseWriter, r *http.Request) {
41 name := r.PathValue("name")
42 name = filepath.Clean(name)
43
44 repo, err := securejoin.SecureJoin(d.c.Repo.ScanPath, name)
45 if err != nil {
46 log.Printf("securejoin error: %v", err)
47 d.Write404(w)
48 return
49 }
50
51 w.Header().Set("content-type", "application/x-git-upload-pack-result")
52 w.Header().Set("Connection", "Keep-Alive")
53 w.Header().Set("Transfer-Encoding", "chunked")
54 w.WriteHeader(http.StatusOK)
55
56 cmd := service.ServiceCommand{
57 Dir: repo,
58 Stdout: w,
59 }
60
61 var reader io.ReadCloser
62 reader = r.Body
63
64 if r.Header.Get("Content-Encoding") == "gzip" {
65 reader, err := gzip.NewReader(r.Body)
66 if err != nil {
67 http.Error(w, err.Error(), 500)
68 log.Printf("git: failed to create gzip reader: %s", err)
69 return
70 }
71 defer reader.Close()
72 }
73
74 cmd.Stdin = reader
75 if err := cmd.UploadPack(); err != nil {
76 http.Error(w, err.Error(), 500)
77 log.Printf("git: failed to execute git-upload-pack %s", err)
78 return
79 }
80}