1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package repo
import (
"fmt"
"html/template"
"net/http"
"os"
"path"
"path/filepath"
"senary/auth"
"senary/common"
"strings"
)
type Repository struct {
config *common.Config
repo string
ac *auth.AuthClient
}
func NewRepository(config *common.Config, repo string, ac *auth.AuthClient) *Repository {
fmt.Printf("serving %v\n", repo)
return &Repository{config: config, repo: repo, ac: ac}
}
type KeyVal struct {
Key string
Val string
}
type StaticDir struct {
RequestBase
Table template.HTML
Title string
Filename string
Breadcrumbs []KeyVal
DirName string
}
func (repo *Repository) ServeTree(w http.ResponseWriter, r *http.Request) {
localFile, found := strings.CutPrefix(r.URL.Path, "/repos/"+repo.repo)
fmt.Printf("serving %v\n", localFile)
if !found {
http.Error(w, fmt.Errorf("file not found").Error(), http.StatusBadRequest)
return
}
if info, err := os.Stat(filepath.Join(repo.config.RepoDir, repo.repo, localFile)); err == nil {
if info.IsDir() {
if !strings.HasSuffix(localFile, "/") {
http.Redirect(w, r, r.URL.String()+"/", http.StatusMovedPermanently)
}
localFile += "/index.html"
}
} else {
http.Error(w, fmt.Errorf("static file not found").Error(), http.StatusBadRequest)
return
}
data, err := os.ReadFile(filepath.Join(repo.config.RepoDir, repo.repo, localFile))
if err != nil {
http.Error(w, fmt.Errorf("repo file not found").Error(), http.StatusBadRequest)
return
}
user := repo.ac.GetAuthInfo(repo.config, r)
title, _ := strings.CutSuffix(localFile, ".html")
breadcrumbs := strings.Split(title, "/")
var breadcrumbsMap []KeyVal
filename := filepath.Base(title)
if !strings.HasSuffix(localFile, "/index.html") {
breadcrumbsMap = make([]KeyVal, len(breadcrumbs)-2)
soafar := path.Join("/repos", repo.repo)
for i, bc := range breadcrumbs[1 : len(breadcrumbs)-1] {
soafar = path.Join(soafar, bc)
breadcrumbsMap[i].Key = bc
breadcrumbsMap[i].Val = soafar
}
} else {
breadcrumbs := strings.Split(filepath.Dir(title), "/")
if len(breadcrumbs) > 2 {
breadcrumbsMap = make([]KeyVal, len(breadcrumbs)-2)
soafar := path.Join("/repos", repo.repo)
for i, bc := range breadcrumbs[1 : len(breadcrumbs)-1] {
soafar = path.Join(soafar, bc)
breadcrumbsMap[i].Key = bc
breadcrumbsMap[i].Val = soafar
}
}
filename = filepath.Base(filepath.Dir(title))
}
err = repo.config.Templates.ExecuteTemplate(w, "dir.tpl.html", StaticDir{Table: template.HTML(data), DirName: filepath.Dir(localFile),
Title: filename,
Breadcrumbs: breadcrumbsMap,
Filename: filename,
RequestBase: RequestBase{
Repo: repo.repo, User: user, ClientID: repo.config.ClientID}})
if err != nil {
http.Error(w, fmt.Errorf("file not found").Error(), http.StatusBadRequest)
}
}
|