package cgi import ( "bytes" "context" "fmt" "path/filepath" "strings" sr "tildegit.org/tjp/sliderule" "tildegit.org/tjp/sliderule/logging" ) func cgiDirectory(protocol sr.ServerProtocol, fsroot, urlroot, cmd string) sr.Handler { fsroot = strings.TrimRight(fsroot, "/") return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { if !strings.HasPrefix(request.Path, urlroot) { return nil } rpath := strings.TrimPrefix(request.Path, urlroot) rpath = strings.Trim(rpath, "/") execpath, pathinfo, err := ResolveCGI(rpath, fsroot) if err != nil { return protocol.TemporaryServerError(err) } if execpath == "" { return nil } workdir := filepath.Dir(execpath) if cmd != "" { execpath = cmd } stderr := &bytes.Buffer{} stdout, exitCode, err := RunCGI(ctx, request, execpath, pathinfo, workdir, stderr) if err != nil { return protocol.TemporaryServerError(err) } if exitCode != 0 { _ = ctx.Value("warnlog").(logging.Logger).Log( "msg", "cgi exited with non-zero exit code", "code", exitCode, "stderr", stderr.String(), ) return protocol.CGIFailure(fmt.Errorf("CGI process exited with status %d", exitCode)) } response, err := protocol.ParseResponse(stdout) if err != nil { return protocol.TemporaryServerError(err) } return response }) }