all repos

mugit @ 88da23a7359ef5095d24302ed438c95c78ddba73

馃惍 git server that your cow will love
6 files changed, 31 insertions(+), 18 deletions(-)
fix: url encode ref names, so '/' and other symbols are supported
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>