all repos — elgit @ 70c5e539567b2aa428b69d3744a26a4fb0f2e4cf

fork of legit: web frontend for git, written in go

routes/handler.go (view raw)

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
105
106
107
108
109
110
111
112
package routes

import (
	"log"
	"net/http"
	"os"
	"path"
	"slices"
	"strings"

	"github.com/dimfeld/httptreemux/v5"

	"go.alanpearce.eu/elgit/config"
)

// Checks for gitprotocol-http(5) specific smells; if found, passes
// the request on to the git http service, else render the web frontend.
func (d *deps) Multiplex(w http.ResponseWriter, r *http.Request, params map[string]string) {
	rest := params["rest"]
	switch params["name"] {
	case "info", "git-upload-pack":
		rest = path.Join(params["name"], params["rest"])
		params["name"] = params["category"]
		params["category"] = ""
	}

	if r.URL.RawQuery == "service=git-receive-pack" {
		w.WriteHeader(http.StatusBadRequest)
		_, err := w.Write([]byte("no pushing allowed!"))
		if err != nil {
			log.Println(err)
			d.Write500(w)

			return
		}

		return
	}

	if rest == "info/refs" &&
		r.URL.RawQuery == "service=git-upload-pack" &&
		r.Method == "GET" {
		d.InfoRefs(w, r, params)
	} else if rest == "git-upload-pack" && r.Method == "POST" {
		d.UploadPack(w, r, params)
	} else if r.Method == "GET" {
		d.RepoIndex(w, r, params)
	}
}

func Handlers(c *config.Config) *httptreemux.TreeMux {
	mux := httptreemux.New()

	projects, err := ReadProjectsList(c)
	if err != nil {
		log.Fatal(err)
	}

	d := deps{
		c,
		projects,
	}

	categories := []string{}
	for _, project := range projects {
		if cat, _, found := strings.Cut(project, string(os.PathSeparator)); found {
			categories = append(categories, cat)
		}
	}
	categories = slices.Compact(categories)

	mux.NotFoundHandler = func(w http.ResponseWriter, r *http.Request) {
		d.Write404(w)
	}

	mux.RedirectTrailingSlash = false

	mux.GET("/", d.Index)
	mux.GET("/static/:file", d.ServeStatic)

	mux.GET("/:name/tree/:ref/*rest", d.RepoTree)
	mux.GET("/:name/blob/:ref/*rest", d.FileContent)
	mux.GET("/:name/tree/:ref/", d.RepoTree)
	mux.GET("/:name/blob/:ref/", d.FileContent)
	mux.GET("/:name/log/:ref", d.Log)
	mux.GET("/:name/archive/:file", d.Archive)
	mux.GET("/:name/commit/:ref", d.Diff)
	mux.GET("/:name/refs/", d.Refs)
	mux.GET("/:name", d.Multiplex)
	mux.POST("/:name", d.Multiplex)
	mux.GET("/:name/", d.Multiplex)
	mux.POST("/:name/", d.Multiplex)
	mux.GET("/:name/*rest", d.Multiplex)
	mux.POST("/:name/*rest", d.Multiplex)

	mux.GET("/:category/:name/tree/:ref/*rest", d.RepoTree)
	mux.GET("/:category/:name/blob/:ref/*rest", d.FileContent)
	mux.GET("/:category/:name/tree/:ref/", d.RepoTree)
	mux.GET("/:category/:name/blob/:ref/", d.FileContent)
	mux.GET("/:category/:name/log/:ref", d.Log)
	mux.GET("/:category/:name/archive/:file", d.Archive)
	mux.GET("/:category/:name/commit/:ref", d.Diff)
	mux.GET("/:category/:name/refs/", d.Refs)
	mux.GET("/:category/:name", d.Multiplex)
	mux.POST("/:category/:name", d.Multiplex)
	mux.GET("/:category/:name/", d.Multiplex)
	mux.POST("/:category/:name/", d.Multiplex)
	mux.GET("/:category/:name/*rest", d.Multiplex)
	mux.POST("/:category/:name/*rest", d.Multiplex)

	return mux
}