diff options
| author | tjpcc <tjp@ctrl-c.club> | 2023-09-28 08:08:48 -0600 |
|---|---|---|
| committer | tjpcc <tjp@ctrl-c.club> | 2023-10-09 08:47:37 -0600 |
| commit | 6e1c25af361dde4c063eccbf769e966df4b65f23 (patch) | |
| tree | d28044cf2db246555deda8db395f2f0a7e786590 /routes.go | |
| parent | b4f45f7c654e87bda6d5e7effb6ac5b5feb29ce0 (diff) | |
config file refactor
Diffstat (limited to 'routes.go')
| -rw-r--r-- | routes.go | 157 |
1 files changed, 12 insertions, 145 deletions
@@ -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) - }) -} |
