Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 18m ago 4b8c9e1d
history blame raw 1.8 KiB
1package server
2
3// The two paths the forge serves that are not pages: a repository's Git
4// transport at <name>.git/…, and the go command's module discovery probe on a
5// module path. Both decide from the first path segment alone, so they run before
6// the mux instead of as routes; a wildcard in a route fills a whole segment, and
7// neither "<name>.git" nor a module path with a package suffix can be written as
8// one.
9
10import (
11 "net/http"
12 "path"
13 "strings"
14
15 "rodent.software/vole/server/githttp"
16)
17
18// forgeHandler is the mux with the non-page paths in front of it. It sits inside
19// the web middleware, so the session, the security headers, the compressor and
20// the page-view recorder behave exactly as they do for a page.
21func (s *Server) forgeHandler(next http.Handler) http.Handler {
22 return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
23 if s.gitTransport(rw, r) {
24 return
25 }
26 if s.Web.GoModuleMeta(rw, r) {
27 return
28 }
29 next.ServeHTTP(rw, r)
30 })
31}
32
33// gitTransport serves a clone or fetch from <name>.git/…, the URL the clone
34// menu and the go-import tag advertise. githttp.Route parses that shape; this
35// only decides whether the request belongs to the transport or to the mux.
36//
37// LFS requests are left to the mux: a client asks <name>.git/info/lfs/…, and
38// those handlers own the batch and object endpoints.
39func (s *Server) gitTransport(rw http.ResponseWriter, r *http.Request) bool {
40 if s.Proxy == nil || s.Cfg == nil || !s.Cfg.GitHTTP {
41 return false
42 }
43 // An unclean path is the mux's business: it redirects to the cleaned one, and
44 // the transport must not be the one place that skips that check.
45 if path.Clean(r.URL.Path) != r.URL.Path {
46 return false
47 }
48 _, rest, ok := githttp.Route(r.URL.Path)
49 if !ok || rest == "" || strings.HasPrefix(rest, "info/lfs") {
50 return false
51 }
52 s.Proxy.ServeHTTP(rw, r)
53 return true
54}
55