summaryrefslogtreecommitdiff
path: root/routes.go
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-09-28 08:08:48 -0600
committertjpcc <tjp@ctrl-c.club>2023-10-09 08:47:37 -0600
commit6e1c25af361dde4c063eccbf769e966df4b65f23 (patch)
treed28044cf2db246555deda8db395f2f0a7e786590 /routes.go
parentb4f45f7c654e87bda6d5e7effb6ac5b5feb29ce0 (diff)
config file refactor
Diffstat (limited to 'routes.go')
-rw-r--r--routes.go157
1 files changed, 12 insertions, 145 deletions
diff --git a/routes.go b/routes.go
index 83f2868..f1f57fd 100644
--- a/routes.go
+++ b/routes.go
@@ -1,157 +1,24 @@
package main
import (
- "context"
- "crypto/sha256"
- "crypto/x509"
- "encoding/hex"
- "os"
- "path/filepath"
- "sort"
- "strings"
-
sr "tildegit.org/tjp/sliderule"
- "tildegit.org/tjp/sliderule/contrib/cgi"
- "tildegit.org/tjp/sliderule/contrib/fs"
- "tildegit.org/tjp/sliderule/contrib/tlsauth"
- "tildegit.org/tjp/sliderule/finger"
- "tildegit.org/tjp/sliderule/gemini"
- "tildegit.org/tjp/sliderule/gemini/gemtext/atomconv"
- "tildegit.org/tjp/sliderule/gopher/gophermap"
- "tildegit.org/tjp/sliderule/logging"
- "tildegit.org/tjp/syw"
)
-func geminiRouter(conf config) sr.Handler {
- fsys := os.DirFS(conf.geminiRoot)
-
- privileged := tlsAuth(conf.privilegedUsers)
-
- router := &sr.Router{}
-
- router.Route(
- "/*",
- gemini.GeminiOnly(true)(sr.FallthroughHandler(
- fs.TitanUpload(privileged, conf.geminiRoot)(postUploadRedirect),
- fs.GeminiFileHandler(fsys),
- fs.GeminiDirectoryDefault(fsys, "index.gmi"),
- fs.GeminiDirectoryListing(fsys, nil),
- )),
- )
-
- router.Route(
- "/cgi-bin/*",
- gemini.GeminiOnly(false)(cgi.GeminiCGIDirectory(
- "/cgi-bin/",
- strings.Join([]string{".", strings.Trim(conf.geminiRoot, "/"), "cgi-bin"}, "/"),
- )),
- )
-
- router.Route(
- "/cgi-bin/private/*",
- gemini.GeminiOnly(false)(tlsauth.GeminiAuth(privileged)(
- cgi.GeminiCGIDirectory("/cgi-bin/private/", strings.Join([]string{
- ".",
- strings.Trim(conf.geminiRoot, "/"),
- "cgi-bin",
- "private",
- }, "/")),
- )),
- )
-
- if conf.geminiRepos != "" {
- router.Mount("/git", syw.GeminiRouter(conf.geminiRepos, nil))
- }
-
- h := router.Handler()
- if conf.geminiAutoAtom {
- h = atomconv.Auto(h)
- }
-
- return h
-}
-
-func gopherRouter(conf config) sr.Handler {
- settings := gophermap.FileSystemSettings{
- ParseExtended: true,
- Exec: true,
- ListUsers: false,
- DirMaps: []string{"gophermap"},
- DirTag: "gophertag",
- }
-
+func routes(server Server) *sr.Router {
router := &sr.Router{}
-
- router.Route(
- "/*",
- sr.FallthroughHandler(
- cgi.ExecGopherMaps("/", conf.gopherRoot, &settings),
- fs.GopherFileHandler(conf.gopherRoot, &settings),
- fs.GopherDirectoryDefault(conf.gopherRoot, &settings),
- fs.GopherDirectoryListing(conf.gopherRoot, &settings),
- ),
- )
-
- router.Route(
- "/cgi-bin/*",
- cgi.GopherCGIDirectory("/cgi-bin/", filepath.Join(conf.gopherRoot, "cgi-bin"), &settings),
- )
-
- if conf.gopherRepos != "" {
- router.Mount("/git", syw.GopherRouter(conf.gopherRepos, nil))
+ for _, route := range server.Routes {
+ addRoute(server, router, route)
}
-
- return router.Handler()
+ return router
}
-var postUploadRedirect = sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
- u := *request.URL
- u.Path = strings.SplitN(u.Path, ";", 2)[0]
- u.Scheme = "gemini"
- return gemini.Redirect(u.String())
-})
-
-func tlsAuth(uploaders []string) tlsauth.Approver {
- sort.Strings(uploaders)
-
- return func(cert *x509.Certificate) bool {
- raw := sha256.Sum256(cert.Raw)
- user := hex.EncodeToString(raw[:])
-
- _, found := sort.Find(len(uploaders), func(i int) int {
- switch {
- case uploaders[i] < user:
- return 1
- case uploaders[i] == user:
- return 0
- default:
- return -1
- }
- })
- return found
+func addRoute(server Server, router *sr.Router, route RouteDirective) {
+ switch server.Type {
+ case "gopher":
+ addGopherRoute(router, route)
+ case "gemini":
+ addGeminiRoute(router, route)
+ default:
+ panic("invalid server type '" + server.Type + "'")
}
}
-
-func fingerHandler(conf config) sr.Handler {
- return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
- name := strings.TrimPrefix(request.Path, "/")
- if name == "" {
- return finger.Error("listings not permitted")
- }
-
- path, ok := conf.fingerResponses[strings.ToLower(name)]
- if !ok {
- return finger.Error("user not found")
- }
-
- file, err := os.Open(path)
- if err != nil {
- ctx.Value("errorlog").(logging.Logger).Log(
- "msg", "finger response file open error",
- "error", err,
- )
- }
-
- return finger.Success(file)
- })
-}