Documentation ¶
Index ¶
- Variables
- func FindDavRoot(addr, fpath string) (root string, ok bool)
- func FtpEscapeBrackets(s string) string
- func GetDavRoot(addr string) (root string, ok bool)
- func HasFoldPrefix(s, prefix string) bool
- func IsTypeIso(fpath string) bool
- func JoinPath(dir, base string) string
- func SetDavRoot(addr, root string)
- func SftpPwd(ftpaddr string, client *sftp.Client) (pwd string, err error)
- func SplitKey(fullpath string) (string, string, bool)
- func SplitUrl(urlpath string) (string, string, bool)
- func ToDirEntry(fi fs.FileInfo) fs.DirEntry
- type Config
- type DavFileInfo
- type DavJoint
- func (j *DavJoint) Busy() bool
- func (j *DavJoint) Cleanup() error
- func (j *DavJoint) Close() (err error)
- func (j *DavJoint) Info(fpath string) (fs.FileInfo, error)
- func (j *DavJoint) Make(base Joint, urladdr string) (err error)
- func (j *DavJoint) Open(fpath string) (file fs.File, err error)
- func (j *DavJoint) Read(b []byte) (n int, err error)
- func (j *DavJoint) ReadAt(b []byte, off int64) (n int, err error)
- func (j *DavJoint) ReadDir(n int) (list []fs.DirEntry, err error)
- func (j *DavJoint) Seek(offset int64, whence int) (abs int64, err error)
- func (j *DavJoint) Size() (int64, error)
- func (j *DavJoint) Stat() (fs.FileInfo, error)
- type FileInfo
- type FtpFileInfo
- func (fi FtpFileInfo) Info() (fs.FileInfo, error)
- func (fi FtpFileInfo) IsDir() bool
- func (fi FtpFileInfo) IsRealDir() bool
- func (fi FtpFileInfo) ModTime() time.Time
- func (fi FtpFileInfo) Mode() fs.FileMode
- func (fi FtpFileInfo) Name() string
- func (fi FtpFileInfo) Size() int64
- func (fi FtpFileInfo) String() string
- func (fi FtpFileInfo) Sys() interface{}
- func (fi FtpFileInfo) Type() fs.FileMode
- type FtpJoint
- func (j *FtpJoint) Busy() bool
- func (j *FtpJoint) ChangeDir(wd string) (err error)
- func (j *FtpJoint) ChangeDirToParent() (err error)
- func (j *FtpJoint) Cleanup() error
- func (j *FtpJoint) Close() (err error)
- func (j *FtpJoint) CurrentDir() (wd string, err error)
- func (j *FtpJoint) Info(fpath string) (fs.FileInfo, error)
- func (j *FtpJoint) Make(base Joint, urladdr string) (err error)
- func (j *FtpJoint) ModTime() (time.Time, error)
- func (j *FtpJoint) Open(fpath string) (file fs.File, err error)
- func (j *FtpJoint) Read(b []byte) (n int, err error)
- func (j *FtpJoint) ReadAt(b []byte, off int64) (n int, err error)
- func (j *FtpJoint) ReadDir(n int) (list []fs.DirEntry, err error)
- func (j *FtpJoint) Seek(offset int64, whence int) (abs int64, err error)
- func (j *FtpJoint) Size() (int64, error)
- func (j *FtpJoint) Stat() (fs.FileInfo, error)
- func (j *FtpJoint) Write(p []byte) (n int, err error)
- type IsoFileInfo
- func (fi IsoFileInfo) Info() (fs.FileInfo, error)
- func (fi IsoFileInfo) IsDir() bool
- func (fi IsoFileInfo) IsRealDir() bool
- func (fi IsoFileInfo) Mode() fs.FileMode
- func (fi IsoFileInfo) Name() string
- func (fi IsoFileInfo) String() string
- func (fi IsoFileInfo) Sys() interface{}
- func (fi IsoFileInfo) Type() fs.FileMode
- type IsoJoint
- func (j *IsoJoint) Busy() bool
- func (j *IsoJoint) Cleanup() (err error)
- func (j *IsoJoint) Close() error
- func (j *IsoJoint) Info(fpath string) (fs.FileInfo, error)
- func (j *IsoJoint) Make(base Joint, isopath string) (err error)
- func (j *IsoJoint) Open(fpath string) (file fs.File, err error)
- func (j *IsoJoint) OpenFile(fpath string) (*iso.File, error)
- func (j *IsoJoint) ReadDir(n int) (list []fs.DirEntry, err error)
- func (j *IsoJoint) Size() (int64, error)
- func (j *IsoJoint) Stat() (fs.FileInfo, error)
- type Joint
- type JointCache
- func (jc *JointCache) Close() (err error)
- func (jc *JointCache) Count() int
- func (jc *JointCache) Eject(j Joint) bool
- func (jc *JointCache) Get() (jw JointWrap, err error)
- func (jc *JointCache) Has(j Joint) bool
- func (jc *JointCache) Key() string
- func (jc *JointCache) Open(fpath string) (f fs.File, err error)
- func (jc *JointCache) Pop() (jw JointWrap, ok bool)
- func (jc *JointCache) Put(j Joint)
- func (jc *JointCache) ReadDir(fpath string) (list []fs.DirEntry, err error)
- func (jc *JointCache) Stat(fpath string) (fi fs.FileInfo, err error)
- type JointFileInfo
- type JointPool
- func (jp *JointPool) Clear() error
- func (jp *JointPool) Close() error
- func (jp *JointPool) GetCache(key string) (jc *JointCache)
- func (jp *JointPool) GetJoint(key string) (j Joint, err error)
- func (jp *JointPool) Keys() []string
- func (jp *JointPool) Open(fullpath string) (f fs.File, err error)
- func (jp *JointPool) ReadDir(fullpath string) (list []fs.DirEntry, err error)
- func (jp *JointPool) Stat(fullpath string) (fi fs.FileInfo, err error)
- func (jp *JointPool) Sub(dir string) (fs.FS, error)
- type JointWrap
- type RFile
- type SftpFileStat
- type SftpJoint
- func (j *SftpJoint) Busy() bool
- func (j *SftpJoint) Cleanup() error
- func (j *SftpJoint) Close() (err error)
- func (j *SftpJoint) Info(fpath string) (fs.FileInfo, error)
- func (j *SftpJoint) Make(base Joint, urladdr string) (err error)
- func (j *SftpJoint) Open(fpath string) (file fs.File, err error)
- func (j *SftpJoint) ReadDir(n int) (list []fs.DirEntry, err error)
- func (j *SftpJoint) Size() (int64, error)
- func (j *SftpJoint) Stat() (fs.FileInfo, error)
- type SubPool
- type SysJoint
- func (j *SysJoint) Busy() bool
- func (j *SysJoint) Cleanup() error
- func (j *SysJoint) Close() (err error)
- func (j *SysJoint) Info(fpath string) (fs.FileInfo, error)
- func (j *SysJoint) Make(base Joint, dir string) (err error)
- func (j *SysJoint) Open(fpath string) (file fs.File, err error)
- func (j *SysJoint) ReadDir(n int) ([]fs.DirEntry, error)
- func (j *SysJoint) Size() (int64, error)
- func (j *SysJoint) Stat() (fs.FileInfo, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrFtpWhence = errors.New("invalid whence at FTP seeker") ErrFtpNegPos = errors.New("negative position at FTP seeker") )
Cfg is singleton with timeouts settings for all joints.
Functions ¶
func FindDavRoot ¶ added in v0.4.0
FindDavRoot returns cached root for given address, or tries to find it from given path.
func FtpEscapeBrackets ¶
FtpEscapeBrackets escapes square brackets at FTP-path. FTP-server does not recognize path with square brackets as is to get a list of files, so such path should be escaped.
Example ¶
package main import ( "fmt" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { fmt.Println(jnt.FtpEscapeBrackets("Music/Denney [2018]")) }
Output: Music/Denney [[]2018[]]
func GetDavRoot ¶ added in v0.4.0
GetDavRoot returns cached WebDAV root for given address.
func HasFoldPrefix ¶ added in v0.4.0
HasFoldPrefix tests whether the string s begins with prefix without case sensitivity.
func IsTypeIso ¶ added in v0.2.0
IsTypeIso checks that endpoint-file in given path has ISO-extension.
func JoinPath ¶ added in v0.4.0
JoinPath performs fast join of two path chunks.
Example ¶
JoinPath can be used for high performance path concatenation.
package main import ( "fmt" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { fmt.Println(jnt.JoinPath("any/path", "fox.txt")) fmt.Println(jnt.JoinPath("any/path/", "fox.txt")) fmt.Println(jnt.JoinPath("any", "/path/fox.txt")) fmt.Println(jnt.JoinPath("any/path/", "/fox.txt")) fmt.Println(jnt.JoinPath("/any/path", "fox.txt")) }
Output: any/path/fox.txt any/path/fox.txt any/path/fox.txt any/path/fox.txt /any/path/fox.txt
func SetDavRoot ¶ added in v0.4.0
func SetDavRoot(addr, root string)
SetDavRoot associates given WebDAV root with address without check up.
func SftpPwd ¶
SftpPwd return SFTP current directory. It's used cache to avoid extra calls to SFTP-server to get current directory for every call.
func SplitKey ¶ added in v0.2.0
SplitKey splits full path to joint key to establish link, and remained local path. Also returns boolean value that given path is not at primary file system.
Example ¶
package main import ( "fmt" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { var list = []string{ "some/path/fox.txt", "testdata/external.iso", "testdata/external.iso/fox.txt", "testdata/external.iso/disk/internal.iso/fox.txt", "ftp://music:x@192.168.1.1:21/Music", "ftp://music:x@192.168.1.1:21/testdata/external.iso/disk/internal.iso/docs/doc1.txt", "https://music:x@example.keenetic.link/webdav/Global%20Underground/Nubreed/", } jnt.SetDavRoot("https://music:x@example.keenetic.link", "/webdav/") for _, s := range list { var key, fpath, _ = jnt.SplitKey(s) fmt.Printf("key: '%s', path: '%s'\n", key, fpath) } }
Output: key: '', path: 'some/path/fox.txt' key: 'testdata/external.iso', path: '' key: 'testdata/external.iso', path: 'fox.txt' key: 'testdata/external.iso/disk/internal.iso', path: 'fox.txt' key: 'ftp://music:x@192.168.1.1:21', path: 'Music' key: 'ftp://music:x@192.168.1.1:21/testdata/external.iso/disk/internal.iso', path: 'docs/doc1.txt' key: 'https://music:x@example.keenetic.link/webdav/', path: 'Global%20Underground/Nubreed/'
func SplitUrl ¶
SplitUrl splits URL to address string and to path as is. For file path it splits to volume name and path at this volume.
Example ¶
package main import ( "fmt" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { var list = []string{ "ftp://music:x@192.168.1.1:21/Music/DJ.m3u", "sftp://music:x@192.168.1.1:22/Video", "https://github.com/schwarzlichtbezirk/joint", "https://pkg.go.dev/github.com/schwarzlichtbezirk/joint", "C:\\Windows\\System", } for _, s := range list { var addr, fpath, url = jnt.SplitUrl(s) fmt.Printf("addr: %s, path: %s, url: %t\n", addr, fpath, url) } }
Output: addr: ftp://music:x@192.168.1.1:21, path: Music/DJ.m3u, url: true addr: sftp://music:x@192.168.1.1:22, path: Video, url: true addr: https://github.com, path: schwarzlichtbezirk/joint, url: true addr: https://pkg.go.dev, path: github.com/schwarzlichtbezirk/joint, url: true addr: C:, path: Windows\System, url: false
Types ¶
type Config ¶
type Config struct { // Timeout to establish connection to FTP-server. DialTimeout time.Duration `json:"dial-timeout" yaml:"dial-timeout" xml:"dial-timeout"` // Expiration duration to keep opened iso-disk structures in cache from last access to it. DiskCacheExpire time.Duration `json:"disk-cache-expire" yaml:"disk-cache-expire" xml:"disk-cache-expire"` }
type DavFileInfo ¶
type DavJoint ¶
type DavJoint struct { io.ReadCloser // contains filtered or unexported fields }
DavJoint keeps gowebdav.Client object. Key is URL to service, address + service route, i.e. https://user:pass@example.com/webdav/.
type FileInfo ¶ added in v0.3.0
FileInfo inherits fs.FileInfo and provide IsDir that returns true for ISO-disk files. Has IsRealDir that provide value from inherited fs.FileInfo.
func ToFileInfo ¶ added in v0.3.0
ToFileInfo converts base fs.FileInfo to FileInfo that compatible both with fs.FileInfo and with fs.DirEntry interface and have derived IsDir.
type FtpFileInfo ¶
FtpFileInfo encapsulates ftp.Entry structure and provides fs.FileInfo implementation.
func (FtpFileInfo) Info ¶ added in v0.3.0
func (fi FtpFileInfo) Info() (fs.FileInfo, error)
Info provided for fs.DirEntry compatibility and returns object itself.
func (FtpFileInfo) IsRealDir ¶ added in v0.3.0
func (fi FtpFileInfo) IsRealDir() bool
func (FtpFileInfo) String ¶ added in v0.3.0
func (fi FtpFileInfo) String() string
func (FtpFileInfo) Sys ¶
func (fi FtpFileInfo) Sys() interface{}
fs.FileInfo implementation. Returns structure pointer itself.
func (FtpFileInfo) Type ¶ added in v0.3.0
func (fi FtpFileInfo) Type() fs.FileMode
type FtpJoint ¶
type FtpJoint struct {
// contains filtered or unexported fields
}
FtpJoint create connection to FTP-server, login with provided by given URL credentials, and gets a once current directory. Key is address of FTP-service, i.e. ftp://user:pass@example.com.
func (*FtpJoint) ChangeDirToParent ¶ added in v0.3.0
func (*FtpJoint) CurrentDir ¶ added in v0.3.0
type IsoFileInfo ¶
func (IsoFileInfo) Info ¶ added in v0.3.0
func (fi IsoFileInfo) Info() (fs.FileInfo, error)
Info provided for fs.DirEntry compatibility and returns object itself.
func (IsoFileInfo) IsDir ¶ added in v0.3.0
func (fi IsoFileInfo) IsDir() bool
func (IsoFileInfo) IsRealDir ¶ added in v0.3.0
func (fi IsoFileInfo) IsRealDir() bool
func (IsoFileInfo) Mode ¶ added in v0.3.0
func (fi IsoFileInfo) Mode() fs.FileMode
func (IsoFileInfo) Name ¶
func (fi IsoFileInfo) Name() string
Name returns filename translated from cyrillic to unicode.
func (IsoFileInfo) String ¶ added in v0.3.0
func (fi IsoFileInfo) String() string
func (IsoFileInfo) Type ¶ added in v0.3.0
func (fi IsoFileInfo) Type() fs.FileMode
type IsoJoint ¶
type IsoJoint struct { Base Joint *iso.File *io.SectionReader // contains filtered or unexported fields }
IsoJoint opens file with ISO9660 disk and prepares disk-structure to access to nested files. Key is external path, to ISO9660-file disk image at local filesystem.
type Joint ¶
type Joint interface { Make(Joint, string) error // establish connection to file system provider Cleanup() error // close connection to file system provider Busy() bool // file is opened fs.FS // open file with local file path io.Closer // close local file Size() (int64, error) // helps to make io.SectionReader fs.ReadDirFile // read directory pointed by local file path RFile }
Joint describes interface with joint to some file system provider.
type JointCache ¶
type JointCache struct {
// contains filtered or unexported fields
}
JointCache implements cache with opened joints to some file system resource.
func NewJointCache ¶
func NewJointCache(key string) *JointCache
func (*JointCache) Close ¶
func (jc *JointCache) Close() (err error)
Close performs close-call to all cached disk joints.
func (*JointCache) Count ¶
func (jc *JointCache) Count() int
Count is number of free joints in cache for one key path.
func (*JointCache) Eject ¶ added in v0.3.0
func (jc *JointCache) Eject(j Joint) bool
Eject joint from the cache.
func (*JointCache) Get ¶
func (jc *JointCache) Get() (jw JointWrap, err error)
Get retrieves cached disk joint, or makes new one.
func (*JointCache) Has ¶
func (jc *JointCache) Has(j Joint) bool
Checks whether it is contained joint in cache.
func (*JointCache) Key ¶ added in v0.2.0
func (jc *JointCache) Key() string
Key is the base address or path for cache file system.
func (*JointCache) Open ¶
func (jc *JointCache) Open(fpath string) (f fs.File, err error)
Open implements fs.FS interface, and returns file that can be casted to joint wrapper. Note that internal ISO-files are considered as directories and it should be provided another JointCache to work with their file system. Use JointPool on this case.
Example ¶
package main import ( "io" "log" "os" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { var jc = jnt.NewJointCache("testdata/external.iso") defer jc.Close() var f, err = jc.Open("fox.txt") if err != nil { log.Fatal(err) } defer f.Close() io.Copy(os.Stdout, f) }
Output: The quick brown fox jumps over the lazy dog.
func (*JointCache) Pop ¶
func (jc *JointCache) Pop() (jw JointWrap, ok bool)
Pop retrieves cached disk joint, and returns ok if it has.
type JointFileInfo ¶ added in v0.5.0
JointFileInfo have additional IsRealDir, which points real file representation.
type JointPool ¶
type JointPool struct {
// contains filtered or unexported fields
}
JointPool is map with joint caches. Each key in map is address or path to file system resource, value - cached for this resource list of joints.
func NewJointPool ¶ added in v0.2.0
func NewJointPool() *JointPool
func (*JointPool) Clear ¶ added in v0.2.0
Clear is same as Close, and removes all entries in the map.
func (*JointPool) GetCache ¶ added in v0.2.0
func (jp *JointPool) GetCache(key string) (jc *JointCache)
GetCache returns cache from pool for given key path, or creates new one.
func (*JointPool) Open ¶ added in v0.2.0
Open opens file with given full path to this file, that can be located inside of nested ISO-images and/or on FTP, SFTP, WebDAV servers. Open implements fs.FS interface, and returns file that can be casted to joint wrapper.
Example ¶
Opens file on joints pool. Path to file can starts with WebDAV/SFTP/FTP service address or at local filesystem, and include ISO9660 disks as chunks of path.
package main import ( "io" "log" "os" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { var jp = jnt.NewJointPool() // can be global declaration defer jp.Close() var f, err = jp.Open("testdata/external.iso/fox.txt") if err != nil { log.Fatal(err) } defer f.Close() io.Copy(os.Stdout, f) }
Output: The quick brown fox jumps over the lazy dog.
func (*JointPool) ReadDir ¶ added in v0.2.0
ReadDir returns directory files fs.DirEntry list pointed by given full path. ReadDir implements ReadDirFS interface.
Example ¶
package main import ( "fmt" "log" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { var jp = jnt.NewJointPool() // can be global declaration defer jp.Close() var files, err = jp.ReadDir("testdata/external.iso/data") if err != nil { log.Fatal(err) } for _, de := range files { if de.IsDir() { fmt.Printf("dir: %s\n", de.Name()) } else { var fi, _ = de.Info() fmt.Printf("file: %s, %d bytes\n", de.Name(), fi.Size()) } } }
Output: dir: docs dir: empty file: lorem1.txt, 2747 bytes file: lorem2.txt, 2629 bytes file: lorem3.txt, 2714 bytes dir: доки file: рыба.txt, 1789 bytes
func (*JointPool) Stat ¶ added in v0.2.0
Stat returns fs.FileInfo of file pointed by given full path. Stat implements fs.StatFS interface.
Example ¶
package main import ( "fmt" "log" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { var jp = jnt.NewJointPool() // can be global declaration defer jp.Close() var fi, err = jp.Stat("testdata/external.iso/fox.txt") if err != nil { log.Fatal(err) } fmt.Printf("name: %s, size: %d\n", fi.Name(), fi.Size()) }
Output: name: fox.txt, size: 44
func (*JointPool) Sub ¶ added in v0.3.0
Sub returns new file subsystem with given absolute root directory. It's assumed that this call can be used to get access to some WebDAV/SFTP/FTP service. Sub implements fs.SubFS interface, and returns object that can be casted to *SubPool.
Example ¶
Open http://localhost:8080/ in browser to get a list of files in ISO-image.
package main import ( "log" "net/http" jnt "github.com/schwarzlichtbezirk/joint" ) func main() { // create map with caches for all currently unused joints var jp = jnt.NewJointPool() // file system, that shares content of "testdata" folder // and all embedded into ISO-disks files var sp, err = jp.Sub("testdata") if err != nil { log.Fatal(err) } http.Handle("/", http.FileServer(http.FS(sp))) log.Fatal(http.ListenAndServe(":8080", nil)) }
Output:
type JointWrap ¶
type JointWrap struct { Joint // contains filtered or unexported fields }
JointWrap helps to return joint into cache after Close-call. It has pointer to JointCache that it binded to.
func (JointWrap) GetCache ¶ added in v0.2.0
func (jw JointWrap) GetCache() *JointCache
GetCache returns binded cache.
type SftpFileStat ¶
type SftpJoint ¶
SftpJoint create SSH-connection to SFTP-server, login with provided by given URL credentials, and gets a once current directory. Key is address of SFTP-service, i.e. sftp://user:pass@example.com.
type SubPool ¶ added in v0.3.0
type SubPool struct { *JointPool // contains filtered or unexported fields }
SubPool releases io/fs interfaces in the way that can be used for http-handlers. It has pointer to pool to share same pool for several derived file subsystems. SubPool is developed to pass fstest.TestFS tests, and all its functions receives only valid FS-paths.
func NewSubPool ¶ added in v0.3.0
NewSubPool creates new SubPool objects with given pool of caches and given absolute root directory.
func (*SubPool) Open ¶ added in v0.3.0
Open implements fs.FS interface, and returns file that can be casted to joint wrapper.