diff options
| author | tjpcc <tjp@ctrl-c.club> | 2023-04-30 17:31:35 -0600 | 
|---|---|---|
| committer | tjpcc <tjp@ctrl-c.club> | 2023-04-30 17:31:35 -0600 | 
| commit | 21e2758145d100d74013060f7090d84679cae683 (patch) | |
| tree | 6723c4fa7eea0f9f5398150a22d0dda59e12a75f /contrib | |
| parent | 7a021631cd9e02abe62610f66567f81062cecfbe (diff) | |
spartan handler for a CGI directory
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/cgi/spartan.go | 46 | 
1 files changed, 46 insertions, 0 deletions
| diff --git a/contrib/cgi/spartan.go b/contrib/cgi/spartan.go new file mode 100644 index 0000000..01ebb19 --- /dev/null +++ b/contrib/cgi/spartan.go @@ -0,0 +1,46 @@ +package cgi + +import ( +	"context" +	"fmt" +	"strings" + +	"tildegit.org/tjp/gus" +	"tildegit.org/tjp/gus/spartan" +) + +// SpartanCGIDirectory runs executable files relative to a root directory in the file system. +// +// It will also find any run any executable _part way_ through the path, so for example a +// request for /foo/bar/baz can also run an executable found at /foo or /foo/bar. In such +// a case the PATH_INFO environment variable will include the remaining portion of the URI. +func SpartanCGIDirectory(pathRoot, fsRoot string) gus.Handler { +	fsRoot = strings.TrimRight(fsRoot, "/") +	return gus.HandlerFunc(func(ctx context.Context, request *gus.Request) *gus.Response { +		if !strings.HasPrefix(request.Path, pathRoot) { +			return nil +		} + +		filepath, pathinfo, err := ResolveCGI(request.Path[len(pathRoot):], fsRoot) +		if err != nil { +			return spartan.ServerError(err) +		} +		if filepath == "" { +			return nil +		} + +		stdout, exitCode, err := RunCGI(ctx, request, filepath, pathinfo) +		if err != nil { +			return spartan.ServerError(err) +		} +		if exitCode != 0 { +			return spartan.ServerError(fmt.Errorf("CGI process exited with status %d", exitCode)) +		} + +		response, err := spartan.ParseResponse(stdout) +		if err != nil { +			return spartan.ServerError(err) +		} +		return response +	}) +} | 
