diff options
Diffstat (limited to 'spartan.go')
| -rw-r--r-- | spartan.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/spartan.go b/spartan.go new file mode 100644 index 0000000..b496385 --- /dev/null +++ b/spartan.go @@ -0,0 +1,111 @@ +package main + +import ( + "context" + "errors" + "fmt" + + sr "tildegit.org/tjp/sliderule" + "tildegit.org/tjp/sliderule/contrib/cgi" + "tildegit.org/tjp/sliderule/contrib/fs" + "tildegit.org/tjp/sliderule/logging" + "tildegit.org/tjp/sliderule/spartan" +) + +func buildSpartanServers(servers []Server, config *Configuration) ([]sr.Server, error) { + _, info, _, errlog := Loggers(config) + + groups := map[string][]*Server{} + for i := range servers { + addr := fmt.Sprintf("%s:%d", servers[i].IP.String(), servers[i].Port) + grp, ok := groups[addr] + if !ok { + groups[addr] = []*Server{&servers[i]} + } else { + groups[addr] = append(grp, &servers[i]) + } + } + + result := []sr.Server{} + for addr, configs := range groups { + _ = info.Log("msg", "starting spartan server", "addr", addr) + var handler sr.Handler + if len(configs) == 1 { + handler = routes(*configs[0]) + } else { + mapping := map[string]sr.Handler{} + for _, config := range configs { + router := routes(*config) + for _, hostname := range config.Hostnames { + mapping[hostname] = router + } + } + + handler = sr.VirtualHosts(mapping, sr.HandlerFunc(func(_ context.Context, _ *sr.Request) *sr.Response { + return spartan.ClientError(errors.New("Proxy request refused")) + })) + } + + var hostname string + for _, conf := range configs { + if len(conf.Hostnames) > 0 { + hostname = conf.Hostnames[0] + break + } + } + + sptnsrv, err := spartan.NewServer( + context.Background(), + hostname, + "tcp", + addr, + logging.LogRequests(info)(handler), + errlog, + ) + if err != nil { + return nil, err + } + + result = append(result, sptnsrv) + } + + return result, nil +} + +func addSpartanRoute(router *sr.Router, route RouteDirective) { + switch route.Type { + case "static": + addSpartanStaticRoute(router, route) + case "cgi": + buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler { + return cgi.SpartanCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd) + }) + case "git": + //TODO + } +} + +func addSpartanStaticRoute(router *sr.Router, route RouteDirective) { + buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler { + handlers := []sr.Handler{} + + if route.Modifiers.Exec { + handlers = append(handlers, cgi.SpartanCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd)) + } + + handlers = append(handlers, fs.SpartanFileHandler(route.FsPath, route.URLPath)) + + if route.Modifiers.DirDefault != "" { + handlers = append( + handlers, + fs.SpartanDirectoryDefault(route.FsPath, route.URLPath, route.Modifiers.DirDefault), + ) + } + + if route.Modifiers.DirList { + handlers = append(handlers, fs.SpartanDirectoryListing(route.FsPath, route.URLPath, nil)) + } + + return sr.FallthroughHandler(handlers...) + }) +} |
