+1
-7
knotserver/routes.go
+1
-7
knotserver/routes.go
···
155
}
156
157
func (h *Handle) Archive(w http.ResponseWriter, r *http.Request) {
158
-
name := displayRepoName(r)
159
-
160
file := chi.URLParam(r, "file")
161
162
// TODO: extend this to add more files compression (e.g.: xz)
···
231
}
232
233
func (h *Handle) Diff(w http.ResponseWriter, r *http.Request) {
234
-
name := displayRepoName(r)
235
-
if h.isIgnored(name) {
236
-
notFound(w)
237
-
return
238
-
}
239
ref := chi.URLParam(r, "ref")
240
241
path := filepath.Join(h.c.Repo.ScanPath, didPath(r))
···
155
}
156
157
func (h *Handle) Archive(w http.ResponseWriter, r *http.Request) {
158
+
name := chi.URLParam(r, "name")
159
file := chi.URLParam(r, "file")
160
161
// TODO: extend this to add more files compression (e.g.: xz)
···
230
}
231
232
func (h *Handle) Diff(w http.ResponseWriter, r *http.Request) {
233
ref := chi.URLParam(r, "ref")
234
235
path := filepath.Join(h.c.Repo.ScanPath, didPath(r))
-94
knotserver/util.go
-94
knotserver/util.go
···
1
package knotserver
2
3
import (
4
-
"fmt"
5
-
"io/fs"
6
-
"log"
7
"net/http"
8
"os"
9
"path/filepath"
10
-
"strings"
11
12
"github.com/go-chi/chi/v5"
13
-
"github.com/icyphox/bild/auth"
14
-
"github.com/icyphox/bild/git"
15
"github.com/microcosm-cc/bluemonday"
16
)
17
···
19
return bluemonday.UGCPolicy().SanitizeBytes([]byte(content))
20
}
21
22
-
func displayRepoName(r *http.Request) string {
23
-
user := r.Context().Value("did").(string)
24
-
name := chi.URLParam(r, "name")
25
-
26
-
handle, err := auth.ResolveIdent(r.Context(), user)
27
-
if err != nil {
28
-
log.Printf("failed to resolve ident: %s: %s", user, err)
29
-
return fmt.Sprintf("%s/%s", user, name)
30
-
}
31
-
32
-
return fmt.Sprintf("@%s/%s", handle.Handle.String(), name)
33
-
}
34
-
35
func didPath(r *http.Request) string {
36
did := chi.URLParam(r, "did")
37
name := chi.URLParam(r, "name")
···
49
}
50
return
51
}
52
-
53
-
func (h *Handle) isUnlisted(name string) bool {
54
-
for _, i := range h.c.Repo.Unlisted {
55
-
if name == i {
56
-
return true
57
-
}
58
-
}
59
-
60
-
return false
61
-
}
62
-
63
-
func (h *Handle) isIgnored(name string) bool {
64
-
for _, i := range h.c.Repo.Ignore {
65
-
if name == i {
66
-
return true
67
-
}
68
-
}
69
-
70
-
return false
71
-
}
72
-
73
-
type repoInfo struct {
74
-
Git *git.GitRepo
75
-
Path string
76
-
Category string
77
-
}
78
-
79
-
func (d *Handle) getAllRepos() ([]repoInfo, error) {
80
-
repos := []repoInfo{}
81
-
max := strings.Count(d.c.Repo.ScanPath, string(os.PathSeparator)) + 2
82
-
83
-
err := filepath.WalkDir(d.c.Repo.ScanPath, func(path string, de fs.DirEntry, err error) error {
84
-
if err != nil {
85
-
return err
86
-
}
87
-
88
-
if de.IsDir() {
89
-
// Check if we've exceeded our recursion depth
90
-
if strings.Count(path, string(os.PathSeparator)) > max {
91
-
return fs.SkipDir
92
-
}
93
-
94
-
if d.isIgnored(path) {
95
-
return fs.SkipDir
96
-
}
97
-
98
-
// A bare repo should always have at least a HEAD file, if it
99
-
// doesn't we can continue recursing
100
-
if _, err := os.Lstat(filepath.Join(path, "HEAD")); err == nil {
101
-
repo, err := git.Open(path, "")
102
-
if err != nil {
103
-
log.Println(err)
104
-
} else {
105
-
relpath, _ := filepath.Rel(d.c.Repo.ScanPath, path)
106
-
repos = append(repos, repoInfo{
107
-
Git: repo,
108
-
Path: relpath,
109
-
Category: d.category(path),
110
-
})
111
-
// Since we found a Git repo, we don't want to recurse
112
-
// further
113
-
return fs.SkipDir
114
-
}
115
-
}
116
-
}
117
-
return nil
118
-
})
119
-
120
-
return repos, err
121
-
}
122
-
123
-
func (d *Handle) category(path string) string {
124
-
return strings.TrimPrefix(filepath.Dir(strings.TrimPrefix(path, d.c.Repo.ScanPath)), string(os.PathSeparator))
125
-
}
126
-
127
func setContentDisposition(w http.ResponseWriter, name string) {
128
h := "inline; filename=\"" + name + "\""
129
w.Header().Add("Content-Disposition", h)
···
1
package knotserver
2
3
import (
4
"net/http"
5
"os"
6
"path/filepath"
7
8
"github.com/go-chi/chi/v5"
9
"github.com/microcosm-cc/bluemonday"
10
)
11
···
13
return bluemonday.UGCPolicy().SanitizeBytes([]byte(content))
14
}
15
16
func didPath(r *http.Request) string {
17
did := chi.URLParam(r, "did")
18
name := chi.URLParam(r, "name")
···
30
}
31
return
32
}
33
func setContentDisposition(w http.ResponseWriter, name string) {
34
h := "inline; filename=\"" + name + "\""
35
w.Header().Add("Content-Disposition", h)