diff options
| author | tjp <tjp@ctrl-c.club> | 2023-11-13 07:25:39 -0700 | 
|---|---|---|
| committer | tjp <tjp@ctrl-c.club> | 2023-11-13 07:27:16 -0700 | 
| commit | 1e0f8e0aaeaf1bd2ee39c02e922238b641bcf88b (patch) | |
| tree | 020e5de91f2343119fed10dede9d2c8262a3cd83 /contrib/cgi/gopher.go | |
| parent | a808b4692656c10bb43e2d54a2f5ef2746d231d5 (diff) | |
refactor contribs to work with a Protocol interface
Diffstat (limited to 'contrib/cgi/gopher.go')
| -rw-r--r-- | contrib/cgi/gopher.go | 155 | 
1 files changed, 2 insertions, 153 deletions
diff --git a/contrib/cgi/gopher.go b/contrib/cgi/gopher.go index 7067a6d..8704904 100644 --- a/contrib/cgi/gopher.go +++ b/contrib/cgi/gopher.go @@ -1,18 +1,11 @@  package cgi  import ( -	"bytes"  	"context" -	"fmt" -	"os" -	"path" -	"path/filepath" -	"strings"  	sr "tildegit.org/tjp/sliderule"  	"tildegit.org/tjp/sliderule/gopher"  	"tildegit.org/tjp/sliderule/gopher/gophermap" -	"tildegit.org/tjp/sliderule/logging"  )  // GopherCGIDirectory runs any executable files relative to a root directory on the file system. @@ -25,151 +18,7 @@ func GopherCGIDirectory(fsroot, urlroot, cmd string, settings *gophermap.FileSys  	if settings == nil || !settings.Exec {  		return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { return nil })  	} -	fsroot = strings.TrimRight(fsroot, "/") -	return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { -		if !strings.HasPrefix(request.Path, urlroot) { -			return nil -		} -		requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/") - -		fullpath, pathinfo, err := resolveGopherCGI(fsroot, requestpath) -		if err != nil { -			return gopher.Error(err).Response() -		} -		if fullpath == "" { -			return nil -		} - -		return runGopherCGI(ctx, request, fullpath, pathinfo, cmd, *settings) -	}) -} - -// ExecGopherMaps runs any gophermaps -func ExecGopherMaps(fsroot, urlroot, cmd string, settings *gophermap.FileSystemSettings) sr.Handler { -	if settings == nil || !settings.Exec { -		return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { return nil }) -	} -	fsroot = strings.TrimRight(fsroot, "/") - -	return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { -		if !strings.HasPrefix(request.Path, urlroot) { -			return nil -		} -		requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/") - -		fullpath := filepath.Join(fsroot, requestpath) -		info, err := os.Stat(fullpath) -		if isNotExistError(err) { -			return nil -		} -		if err != nil { -			return gopher.Error(err).Response() -		} - -		if info.IsDir() { -			for _, fname := range settings.DirMaps { -				fpath := filepath.Join(fullpath, fname) -				finfo, err := os.Stat(fpath) -				if isNotExistError(err) { -					continue -				} -				if err != nil { -					return gopher.Error(err).Response() -				} - -				m := finfo.Mode() -				if m.IsDir() { -					continue -				} -				if !m.IsRegular() || m&5 != 5 { -					continue -				} -				return runGopherCGI(ctx, request, fpath, "/", cmd, *settings) -			} - -			return nil -		} - -		m := info.Mode() -		if !m.IsRegular() || m&5 != 5 { -			return nil -		} - -		return runGopherCGI(ctx, request, fullpath, "/", cmd, *settings) -	}) -} - -func runGopherCGI( -	ctx context.Context, -	request *sr.Request, -	fullpath string, -	pathinfo string, -	cmd string, -	settings gophermap.FileSystemSettings, -) *sr.Response { -	workdir := filepath.Dir(fullpath) -	if cmd != "" { -		fullpath = cmd -	} - -	stderr := &bytes.Buffer{} -	stdout, exitCode, err := RunCGI(ctx, request, fullpath, pathinfo, workdir, stderr) -	if err != nil { -		return gopher.Error(err).Response() -	} -	if exitCode != 0 { -		ctx.Value("warnlog").(logging.Logger).Log( -			"msg", "cgi exited with non-zero exit code", -			"code", exitCode, -			"stderr", stderr.String(), -		) -		return gopher.Error( -			fmt.Errorf("CGI process exited with status %d", exitCode), -		).Response() -	} - -	if settings.ParseExtended { -		edoc, err := gophermap.ParseExtended(stdout, request.URL) -		if err != nil { -			return gopher.Error(err).Response() -		} - -		doc, _, err := edoc.Compatible(filepath.Dir(fullpath), settings) -		if err != nil { -			return gopher.Error(err).Response() -		} -		return doc.Response() -	} - -	return gopher.File(gopher.MenuType, stdout) -} - -func resolveGopherCGI(fsRoot string, reqPath string) (string, string, error) { -	segments := append([]string{""}, strings.Split(reqPath, "/")...) -	fullpath := fsRoot -	for i, segment := range segments { -		fullpath = filepath.Join(fullpath, segment) - -		info, err := os.Stat(fullpath) -		if isNotExistError(err) { -			return "", "", nil -		} -		if err != nil { -			return "", "", err -		} - -		if !info.IsDir() { -			if info.Mode()&5 == 5 { -				pathinfo := "/" -				if len(segments) > i+1 { -					pathinfo = path.Join(segments[i:]...) -				} -				return fullpath, pathinfo, nil -			} -			break -		} -	} - -	return "", "", nil +	handler := cgiDirectory(gopher.ServerProtocol, fsroot, urlroot, cmd) +	return gophermap.ExtendMiddleware(fsroot, urlroot, settings)(handler)  }  | 
