6 files changed,
31 insertions(+),
18 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-02-24 17:51:49 +0200
Authored at:
2026-02-24 17:35:51 +0200
Change ID:
vlnyqplsrowyznxmulrynvqpwnonxoup
Parent:
75fc9d1
M
internal/handlers/git.go
路路路 65 65 } 66 66 67 67 func (h *handlers) archiveHandler(w http.ResponseWriter, r *http.Request) { 68 - ref := r.PathValue("ref") 68 + ref := h.parseRef(r.PathValue("ref")) 69 69 name := r.PathValue("name") 70 70 path, err := h.checkRepoPublicityAndGetPath(name) 71 71 if err != nil {
M
internal/handlers/handlers.go
路路路 3 3 import ( 4 4 "html/template" 5 5 "net/http" 6 + "net/url" 6 7 "path/filepath" 7 8 "strings" 8 9 "time" 路路路 59 60 http.ServeFileFS(w, r, web.StaticFS, f) 60 61 } 61 62 63 +// parseRef parses url encoded ref name. 64 +// If it fails it falls back to raw provided value. 65 +func (h handlers) parseRef(name string) string { 66 + ref, err := url.PathUnescape(name) 67 + if err != nil { 68 + return name 69 + } 70 + return ref 71 +} 72 + 62 73 var templateFuncs = template.FuncMap{ 63 74 "humanizeRelTime": func(t time.Time) string { return humanize.Time(t) }, 64 75 "humanizeTime": func(t time.Time) string { return t.Format("2006-01-02 15:04:05 MST") }, 76 + "urlencode": func(s string) string { return url.PathEscape(s) }, 65 77 "commitSummary": func(s string) string { 66 78 before, after, found := strings.Cut(s, "\n") 67 79 first := strings.TrimSuffix(before, "\r")
M
internal/handlers/repo.go
路路路 124 124 125 125 func (h *handlers) repoTreeHandler(w http.ResponseWriter, r *http.Request) { 126 126 name := r.PathValue("name") 127 - ref := r.PathValue("ref") 127 + ref := h.parseRef(r.PathValue("ref")) 128 128 treePath := r.PathValue("rest") 129 129 130 130 repo, err := h.openPublicRepo(name, ref) 路路路 175 175 176 176 func (h *handlers) fileContentsHandler(w http.ResponseWriter, r *http.Request) { 177 177 name := r.PathValue("name") 178 - ref := r.PathValue("ref") 178 + ref := h.parseRef(r.PathValue("ref")) 179 179 treePath := r.PathValue("rest") 180 180 181 181 var raw bool 路路路 246 246 247 247 func (h *handlers) logHandler(w http.ResponseWriter, r *http.Request) { 248 248 name := r.PathValue("name") 249 - ref := r.PathValue("ref") 249 + ref := h.parseRef(r.PathValue("ref")) 250 250 251 251 repo, err := h.openPublicRepo(name, ref) 252 252 if err != nil { 路路路 281 281 282 282 func (h *handlers) commitHandler(w http.ResponseWriter, r *http.Request) { 283 283 name := r.PathValue("name") 284 - ref := r.PathValue("ref") 284 + ref := h.parseRef(r.PathValue("ref")) 285 + 285 286 repo, err := h.openPublicRepo(name, ref) 286 287 if err != nil { 287 288 h.write404(w, err)
M
web/templates/_repo_header.html
路路路 18 18 <ul> 19 19 <li><a href="/{{ .RepoName }}">summary</a></li> 20 20 <li><a href="/{{ .RepoName }}/refs">refs</a></li> 21 - <li><a href="/{{ .RepoName }}/tree/{{ .P.Ref }}/">tree</a></li> 22 - <li><a href="/{{ .RepoName }}/log/{{ .P.Ref }}">log</a></li> 21 + <li><a href="/{{ .RepoName }}/tree/{{ urlencode .P.Ref }}/">tree</a></li> 22 + <li><a href="/{{ .RepoName }}/log/{{ urlencode .P.Ref }}">log</a></li> 23 23 </ul> 24 24 </nav> 25 25 {{- end }}
M
web/templates/repo_refs.html
路路路 13 13 {{ range .P.Branches }} 14 14 <div> 15 15 <strong>{{ .Name }}</strong> 16 - <a class="link" href="/{{ $repo }}/tree/{{ .Name }}/">browse</a> 17 - <a class="link" href="/{{ $repo }}/log/{{ .Name }}">log</a> 18 - <a class="link" href="/{{ $repo }}/archive/{{ .Name }}">tar.gz</a> 16 + <a class="link" href="/{{ $repo }}/tree/{{ urlencode .Name }}/">browse</a> 17 + <a class="link" href="/{{ $repo }}/log/{{ urlencode .Name }}">log</a> 18 + <a class="link" href="/{{ $repo }}/archive/{{ urlencode .Name }}">tar.gz</a> 19 19 </div> 20 20 {{ end }} 21 21 </div> 路路路 25 25 {{ range .P.Tags }} 26 26 <div> 27 27 <strong>{{ .Name }}</strong> 28 - <a class="link" href="/{{ $repo }}/tree/{{ .Name }}/">browse</a> 29 - <a class="link" href="/{{ $repo }}/log/{{ .Name }}">log</a> 30 - <a class="link" href="/{{ $repo }}/archive/{{ .Name }}">tar.gz</a> 28 + <a class="link" href="/{{ $repo }}/tree/{{ urlencode .Name }}/">browse</a> 29 + <a class="link" href="/{{ $repo }}/log/{{ urlencode .Name }}">log</a> 30 + <a class="link" href="/{{ $repo }}/archive/{{ urlencode .Name }}">tar.gz</a> 31 31 {{ if .Message }} 32 32 <details class="tag-message"> 33 33 <summary>{{ .Name }} message </summary>
M
web/templates/repo_tree.html
路路路 24 24 <tr> 25 25 <td class="mode nowrap"></td> 26 26 <td class="size nowrap"></td> 27 - <td class="fill"><a href="/{{ $name }}/tree/{{ $ref }}/{{ .P.DotDot }}">..</a></td> 27 + <td class="fill"><a href="/{{ $name }}/tree/{{ urlencode $ref }}/{{ .P.DotDot }}">..</a></td> 28 28 </tr> 29 29 {{ end }} 30 30 路路路 35 35 <td class="size nowrap">{{ .Size }}</td> 36 36 <td class="fill"> 37 37 {{ if $parent }} 38 - <a href="/{{ $name}}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a> 38 + <a href="/{{ $name}}/tree/{{ urlencode $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a> 39 39 {{ else }} 40 - <a href="/{{ $name }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a> 40 + <a href="/{{ $name }}/tree/{{ urlencode $ref }}/{{ .Name }}">{{ .Name }}/</a> 41 41 {{ end }} 42 42 </td> 43 43 </tr> 路路路 51 51 <td class="size nowrap">{{ .Size }}</td> 52 52 <td class="fill"> 53 53 {{ if $parent }} 54 - <a href="/{{ $name }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a> 54 + <a href="/{{ $name }}/blob/{{ urlencode $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a> 55 55 {{ else }} 56 - <a href="/{{ $name }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a> 56 + <a href="/{{ $name }}/blob/{{ urlencode $ref }}/{{ .Name }}">{{ .Name }}</a> 57 57 {{ end }} 58 58 </td> 59 59 </tr>