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() }) }