|
@@ -3,7 +3,6 @@ package webdavfs
|
|
|
import (
|
|
|
"errors"
|
|
|
"io"
|
|
|
- "io/fs"
|
|
|
"log"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
@@ -164,61 +163,64 @@ func (e WebDAVFileSystem) Glob(wildcard string) ([]string, error) {
|
|
|
//Handle case for listing root, "*"
|
|
|
wildcard = "/" + wildcard
|
|
|
}
|
|
|
-
|
|
|
- //Get the longest path without *
|
|
|
- chunksWithoutStar := []string{}
|
|
|
- chunks := strings.Split(wildcard, "/")
|
|
|
- for _, chunk := range chunks {
|
|
|
- if !strings.Contains(chunk, "*") {
|
|
|
- chunksWithoutStar = append(chunksWithoutStar, chunk)
|
|
|
- } else {
|
|
|
- //Cut off
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if strings.Count(wildcard, "*") <= 1 && strings.Contains(chunks[len(chunks)-1], "*") {
|
|
|
- //Fast Glob
|
|
|
- fileInfos, err := e.c.ReadDir(filterFilepath(filepath.ToSlash(filepath.Clean(filepath.Dir(wildcard)))))
|
|
|
- if err != nil {
|
|
|
- return []string{}, err
|
|
|
- }
|
|
|
-
|
|
|
- validFiles := []string{}
|
|
|
- matchingRule := wildCardToRegexp(wildcard)
|
|
|
- for _, thisFileInfo := range fileInfos {
|
|
|
- thisFileFullpath := filepath.ToSlash(filepath.Join(filepath.Dir(wildcard), thisFileInfo.Name()))
|
|
|
- match, _ := regexp.MatchString(matchingRule, thisFileFullpath)
|
|
|
- if match {
|
|
|
- validFiles = append(validFiles, thisFileFullpath)
|
|
|
+ chunks := strings.Split(strings.TrimPrefix(wildcard, "/"), "/")
|
|
|
+ results, err := e.globpath("/", chunks, 0)
|
|
|
+ return results, err
|
|
|
+ /*
|
|
|
+ //Get the longest path without *
|
|
|
+ chunksWithoutStar := []string{}
|
|
|
+ chunks := strings.Split(wildcard, "/")
|
|
|
+ for _, chunk := range chunks {
|
|
|
+ if !strings.Contains(chunk, "*") {
|
|
|
+ chunksWithoutStar = append(chunksWithoutStar, chunk)
|
|
|
+ } else {
|
|
|
+ //Cut off
|
|
|
+ break
|
|
|
}
|
|
|
}
|
|
|
- return validFiles, nil
|
|
|
- } else {
|
|
|
- //Slow Glob
|
|
|
- walkRoot := strings.Join(chunksWithoutStar, "/")
|
|
|
- if !strings.HasPrefix(walkRoot, "/") {
|
|
|
- walkRoot = "/" + walkRoot
|
|
|
- }
|
|
|
|
|
|
- allFiles := []string{}
|
|
|
- e.Walk(walkRoot, func(path string, info fs.FileInfo, err error) error {
|
|
|
- allFiles = append(allFiles, path)
|
|
|
- return nil
|
|
|
- })
|
|
|
+ if strings.Count(wildcard, "*") <= 1 && strings.Contains(chunks[len(chunks)-1], "*") {
|
|
|
+ //Fast Glob
|
|
|
+ fileInfos, err := e.c.ReadDir(filterFilepath(filepath.ToSlash(filepath.Clean(filepath.Dir(wildcard)))))
|
|
|
+ if err != nil {
|
|
|
+ return []string{}, err
|
|
|
+ }
|
|
|
|
|
|
- validFiles := []string{}
|
|
|
- matchingRule := wildCardToRegexp(wildcard) + "$"
|
|
|
- for _, thisFilepath := range allFiles {
|
|
|
- match, _ := regexp.MatchString(matchingRule, thisFilepath)
|
|
|
- if match {
|
|
|
- validFiles = append(validFiles, thisFilepath)
|
|
|
+ validFiles := []string{}
|
|
|
+ matchingRule := wildCardToRegexp(wildcard)
|
|
|
+ for _, thisFileInfo := range fileInfos {
|
|
|
+ thisFileFullpath := filepath.ToSlash(filepath.Join(filepath.Dir(wildcard), thisFileInfo.Name()))
|
|
|
+ match, _ := regexp.MatchString(matchingRule, thisFileFullpath)
|
|
|
+ if match {
|
|
|
+ validFiles = append(validFiles, thisFileFullpath)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return validFiles, nil
|
|
|
+ } else {
|
|
|
+ //Slow Glob
|
|
|
+ walkRoot := strings.Join(chunksWithoutStar, "/")
|
|
|
+ if !strings.HasPrefix(walkRoot, "/") {
|
|
|
+ walkRoot = "/" + walkRoot
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return validFiles, nil
|
|
|
+ allFiles := []string{}
|
|
|
+ e.Walk(walkRoot, func(path string, info fs.FileInfo, err error) error {
|
|
|
+ allFiles = append(allFiles, path)
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+
|
|
|
+ validFiles := []string{}
|
|
|
+ matchingRule := wildCardToRegexp(wildcard) + "$"
|
|
|
+ for _, thisFilepath := range allFiles {
|
|
|
+ match, _ := regexp.MatchString(matchingRule, thisFilepath)
|
|
|
+ if match {
|
|
|
+ validFiles = append(validFiles, thisFilepath)
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ return validFiles, nil
|
|
|
+ }
|
|
|
+ */
|
|
|
}
|
|
|
func (e WebDAVFileSystem) GetFileSize(filename string) int64 {
|
|
|
filename = filterFilepath(filepath.ToSlash(filepath.Clean(filename)))
|
|
@@ -302,14 +304,67 @@ func (e WebDAVFileSystem) walk(thisPath string, walkFun filepath.WalkFunc) error
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
-func (e WebDAVFileSystem) globscan(currentPath string, wildcardChunks []string, layer int) ([]string, error) {
|
|
|
- if layer >= len(wildcardChunks) {
|
|
|
+func (e WebDAVFileSystem) globpath(currentPath string, pathSegments []string, depth int) ([]string, error) {
|
|
|
+ const pathSeparatorsLimit = 1000
|
|
|
+ if depth == pathSeparatorsLimit {
|
|
|
+ return nil, errors.New("bad pattern")
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check pattern is well-formed.
|
|
|
+ if _, err := regexp.MatchString(wildCardToRegexp(strings.Join(pathSegments, "/")), ""); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(pathSegments) == 0 {
|
|
|
+ //Reaching the bottom
|
|
|
return []string{}, nil
|
|
|
}
|
|
|
|
|
|
+ thisSegment := pathSegments[0]
|
|
|
+ if strings.Contains(thisSegment, "*") {
|
|
|
+ //Search for matching
|
|
|
+ matchPattern := currentPath + thisSegment
|
|
|
+ files, err := e.c.ReadDir(currentPath)
|
|
|
+ if err != nil {
|
|
|
+ return []string{}, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check which file in the currentPath matches the wildcard
|
|
|
+ matchedSubpaths := []string{}
|
|
|
+ for _, file := range files {
|
|
|
+ thisPath := currentPath + file.Name()
|
|
|
+ match, _ := regexp.MatchString(wildCardToRegexp(matchPattern), thisPath)
|
|
|
+ if match {
|
|
|
+ if file.IsDir() {
|
|
|
+ matchedSubpaths = append(matchedSubpaths, thisPath+"/")
|
|
|
+ } else {
|
|
|
+ matchedSubpaths = append(matchedSubpaths, thisPath)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(pathSegments[1:]) == 0 {
|
|
|
+ return matchedSubpaths, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ //For each of the subpaths, do a globpath
|
|
|
+ matchingFilenames := []string{}
|
|
|
+ for _, subpath := range matchedSubpaths {
|
|
|
+ thisMatchedNames, _ := e.globpath(subpath, pathSegments[1:], depth+1)
|
|
|
+ matchingFilenames = append(matchingFilenames, thisMatchedNames...)
|
|
|
+ }
|
|
|
+ return matchingFilenames, nil
|
|
|
+ } else {
|
|
|
+ //Check folder exists
|
|
|
+ if e.FileExists(currentPath+thisSegment) && e.IsDir(currentPath+thisSegment) {
|
|
|
+ return e.globpath(currentPath+thisSegment+"/", pathSegments[1:], depth+1)
|
|
|
+ } else {
|
|
|
+ //Not matching
|
|
|
+ return []string{}, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-*/
|
|
|
|
|
|
func filterFilepath(rawpath string) string {
|
|
|
rawpath = strings.TrimSpace(rawpath)
|