summaryrefslogtreecommitdiff
path: root/contrib/fs/gopher.go
blob: 22cdbc328ad052078a23a146db315f8d00516862 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package fs

import (
	"context"
	"strings"

	sr "tildegit.org/tjp/sliderule"
	"tildegit.org/tjp/sliderule/gopher"
	"tildegit.org/tjp/sliderule/gopher/gophermap"
)

// GopherFileHandler builds a handler which serves up files from a file system.
//
// It only serves responses for paths which correspond to files, not directories.
func GopherFileHandler(fsroot, urlroot string, settings *gophermap.FileSystemSettings) sr.Handler {
	handler := fileHandler(gopher.ServerProtocol, fsroot, urlroot)
	return gophermap.ExtendMiddleware(fsroot, urlroot, settings)(handler)
}

// GopherDirectoryDefault serves up default files for directory path requests.
//
// If any of the supported filenames are found in the requested directory, the
// contents of that file is returned as the gopher response.
//
// It returns nil for any paths which don't correspond to a directory.
func GopherDirectoryDefault(fsroot, urlroot string, settings *gophermap.FileSystemSettings) sr.Handler {
	if settings == nil {
		return sr.HandlerFunc(func(_ context.Context, _ *sr.Request) *sr.Response { return nil })
	}

	handler := directoryDefault(gopher.ServerProtocol, fsroot, urlroot, false, settings.DirMaps...)

	// force response status to MenuType since we hit a directory default file
	menuHandler := sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
		response := handler.Handle(ctx, request)
		if response == nil {
			return response
		}
		response.Status = gopher.MenuType
		return response
	})

	return gophermap.ExtendMiddleware(fsroot, urlroot, settings)(menuHandler)
}

// GopherDirectoryListing produces a listing of the contents of any requested directories.
//
// It returns nil for any paths which don't correspond to a filesystem directory.
func GopherDirectoryListing(fsroot, urlroot string, settings *gophermap.FileSystemSettings) 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
		}

		dpath, _ := rebasePath(fsroot, urlroot, request)

		if isPrivate(dpath) {
			return nil
		}
		if isd, err := isDir(dpath); err != nil {
			return gopher.Error(err).Response()
		} else if !isd {
			return nil
		}

		if settings == nil {
			settings = &gophermap.FileSystemSettings{}
		}
		doc, err := gophermap.ListDir(dpath, request.URL, *settings)
		if err != nil {
			return gopher.Error(err).Response()
		}

		return doc.Response()
	})
}