From 173e1528be116f7f8d9520f27eb732bda4f35fa5 Mon Sep 17 00:00:00 2001 From: Seednode Date: Sat, 16 Sep 2023 20:15:39 -0500 Subject: [PATCH] Rewrite filewalk functions, add (incomplete) to logging when -v|--verbose is passed and a broken pipe error is received --- cmd/files.go | 60 ++++++++++++++++++++-------------------------------- cmd/root.go | 2 +- cmd/web.go | 47 +++++++++++++++++++++++++++++++++------- 3 files changed, 63 insertions(+), 46 deletions(-) diff --git a/cmd/files.go b/cmd/files.go index e5893d7..f662d6c 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -13,7 +13,6 @@ import ( "crypto/rand" "os" "path/filepath" - "runtime" "strconv" "strings" "sync" @@ -94,16 +93,30 @@ func kill(path string, cache *fileCache) error { return nil } -func preparePath(path string) string { - if runtime.GOOS == "windows" { - return fmt.Sprintf("%s/%s", mediaPrefix, filepath.ToSlash(path)) +func split(path string, regexes *regexes) (*splitPath, error) { + p := splitPath{} + var err error + + split := regexes.filename.FindAllStringSubmatch(path, -1) + + if len(split) < 1 || len(split[0]) < 3 { + return &splitPath{}, nil } - return mediaPrefix + path + p.base = split[0][1] + + p.number, err = strconv.Atoi(split[0][2]) + if err != nil { + return &splitPath{}, err + } + + p.extension = split[0][3] + + return &p, nil } -func newFile(paths []string, filters *filters, sortOrder string, regexes *regexes, cache *fileCache, formats *types.Types) (string, error) { - path, err := pickFile(paths, filters, sortOrder, cache, formats) +func newFile(list []string, sortOrder string, regexes *regexes, formats *types.Types) (string, error) { + path, err := pickFile(list) if err != nil { return "", err } @@ -169,28 +182,6 @@ func nextFile(path, sortOrder string, regexes *regexes, formats *types.Types) (s return fileName, err } -func split(path string, regexes *regexes) (*splitPath, error) { - p := splitPath{} - var err error - - split := regexes.filename.FindAllStringSubmatch(path, -1) - - if len(split) < 1 || len(split[0]) < 3 { - return &splitPath{}, nil - } - - p.base = split[0][1] - - p.number, err = strconv.Atoi(split[0][2]) - if err != nil { - return &splitPath{}, err - } - - p.extension = split[0][3] - - return &p, nil -} - func tryExtensions(splitPath *splitPath, formats *types.Types) (string, error) { var fileName string @@ -297,7 +288,7 @@ func pathCount(path string) (int, int, error) { return files, directories, nil } -func scanPath(path string, fileChannel chan<- string, fileScans chan int, stats *scanStatsChannels, formats *types.Types) error { +func walkPath(path string, fileChannel chan<- string, fileScans chan int, stats *scanStatsChannels, formats *types.Types) error { var wg sync.WaitGroup errorChannel := make(chan error) @@ -409,7 +400,7 @@ func scanPaths(paths []string, sort string, cache *fileCache, formats *types.Typ <-directoryScans }() - err := scanPath(paths[i], fileChannel, fileScans, statsChannels, formats) + err := walkPath(paths[i], fileChannel, fileScans, statsChannels, formats) if err != nil { errorChannel <- err @@ -501,12 +492,7 @@ func fileList(paths []string, filters *filters, sort string, cache *fileCache, f } } -func pickFile(args []string, filters *filters, sort string, cache *fileCache, formats *types.Types) (string, error) { - list, err := fileList(args, filters, sort, cache, formats) - if err != nil { - return "", err - } - +func pickFile(list []string) (string, error) { fileCount := len(list) if fileCount < 1 { diff --git a/cmd/root.go b/cmd/root.go index 5e6f87d..791bce8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -11,7 +11,7 @@ import ( ) const ( - ReleaseVersion string = "0.90.4" + ReleaseVersion string = "0.91.0" ) var ( diff --git a/cmd/web.go b/cmd/web.go index 5d80f64..e8956f1 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -19,6 +19,7 @@ import ( "strconv" "strings" "sync" + "syscall" "time" "github.com/julienschmidt/httprouter" @@ -40,6 +41,14 @@ const ( timeout time.Duration = 10 * time.Second ) +func preparePath(path string) string { + if runtime.GOOS == "windows" { + return fmt.Sprintf("%s/%s", mediaPrefix, filepath.ToSlash(path)) + } + + return mediaPrefix + path +} + func serveStaticFile(paths []string, cache *fileCache, errorChannel chan<- error) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { prefix := Prefix + sourcePrefix @@ -96,7 +105,19 @@ func serveStaticFile(paths []string, cache *fileCache, errorChannel chan<- error return } - written, _ := w.Write(buf) + var status string + + written, err := w.Write(buf) + switch { + case errors.Is(err, syscall.EPIPE): + status = " (incomplete)" + case err != nil: + errorChannel <- err + + serverError(w, r, nil) + + return + } refererUri, err := stripQueryParams(refererToUri(r.Referer())) if err != nil { @@ -119,12 +140,13 @@ func serveStaticFile(paths []string, cache *fileCache, errorChannel chan<- error } if Verbose { - fmt.Printf("%s | Serve: %s (%s) to %s in %s\n", + fmt.Printf("%s | Serve: %s (%s) to %s in %s%s\n", startTime.Format(logDate), filePath, humanReadableSize(written), realIP(r), time.Since(startTime).Round(time.Microsecond), + status, ) } } @@ -152,10 +174,10 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type _, refreshInterval := refreshInterval(r) - var filePath string + var path string if refererUri != "" { - filePath, err = nextFile(strippedRefererUri, sortOrder, regexes, formats) + path, err = nextFile(strippedRefererUri, sortOrder, regexes, formats) if err != nil { errorChannel <- err @@ -165,6 +187,15 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type } } + list, err := fileList(paths, filters, sortOrder, cache, formats) + if err != nil { + errorChannel <- err + + serverError(w, r, nil) + + return + } + loop: for timeout := time.After(timeout); ; { select { @@ -173,14 +204,14 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type default: } - if filePath != "" { + if path != "" { break loop } - filePath, err = newFile(paths, filters, sortOrder, regexes, cache, formats) + path, err = newFile(list, sortOrder, regexes, formats) switch { case err != nil && err == ErrNoMediaFound: - notFound(w, r, filePath) + notFound(w, r, path) return case err != nil: @@ -197,7 +228,7 @@ func serveRoot(paths []string, regexes *regexes, cache *fileCache, formats *type newUrl := fmt.Sprintf("http://%s%s%s%s", r.Host, Prefix, - preparePath(filePath), + preparePath(path), queryParams, ) http.Redirect(w, r, newUrl, RedirectStatusCode)