Restructured code to hopefully be more readable

This commit is contained in:
Seednode 2022-09-26 12:31:45 -05:00
parent 7fe46868c5
commit 919d1c2e8b
3 changed files with 113 additions and 89 deletions

View File

@ -30,10 +30,9 @@ func appendPaths(m map[string][]string, path, filter string) (map[string][]strin
directory, _ := filepath.Split(absolutePath) directory, _ := filepath.Split(absolutePath)
switch { if filter != "" && strings.Contains(path, filter) {
case filter != "" && strings.Contains(path, filter):
m[directory] = append(m[directory], path) m[directory] = append(m[directory], path)
case filter == "": } else if filter == "" {
m[directory] = append(m[directory], path) m[directory] = append(m[directory], path)
} }
@ -55,7 +54,7 @@ func getFirstFile(path string) (string, error) {
fileName := fmt.Sprintf("%v%.3d%v", base, number, extension) fileName := fmt.Sprintf("%v%.3d%v", base, number, extension)
nextFile, err := checkNextFile(fileName) nextFile, err := nextFileExists(fileName)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -87,7 +86,7 @@ func getNextFile(path string) (string, error) {
fileName := fmt.Sprintf("%v%.3d%v", base, incremented, extension) fileName := fmt.Sprintf("%v%.3d%v", base, incremented, extension)
nextFile, err := checkNextFile(fileName) nextFile, err := nextFileExists(fileName)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -99,7 +98,40 @@ func getNextFile(path string) (string, error) {
return fileName, nil return fileName, nil
} }
func checkNextFile(path string) (bool, error) { func pathIsValid(filePath string, paths []string) bool {
var matchesPrefix = false
for i := 0; i < len(paths); i++ {
if strings.HasPrefix(filePath, paths[i]) {
matchesPrefix = true
}
}
if !matchesPrefix {
if Verbose {
fmt.Printf("%v Failed to serve file outside specified path(s): %v\n", time.Now().Format(LOGDATE), filePath)
}
return false
}
return true
}
func fileExists(filePath string) (bool, error) {
_, err := os.Stat(filePath)
if errors.Is(err, os.ErrNotExist) {
if Verbose {
fmt.Printf("%v Failed to serve non-existent file: %v\n", time.Now().Format(LOGDATE), filePath)
}
return false, nil
} else if !errors.Is(err, os.ErrNotExist) && err != nil {
return false, err
}
return true, nil
}
func nextFileExists(path string) (bool, error) {
_, err := os.Stat(path) _, err := os.Stat(path)
switch { switch {
case err == nil: case err == nil:
@ -111,7 +143,7 @@ func checkNextFile(path string) (bool, error) {
} }
} }
func checkIfImage(path string) (bool, error) { func isImage(path string) (bool, error) {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
return false, err return false, err
@ -121,11 +153,7 @@ func checkIfImage(path string) (bool, error) {
head := make([]byte, 261) head := make([]byte, 261)
file.Read(head) file.Read(head)
if filetype.IsImage(head) { return filetype.IsImage(head), nil
return true, nil
}
return false, nil
} }
func getFiles(m map[string][]string, path, filter string) (map[string][]string, error) { func getFiles(m map[string][]string, path, filter string) (map[string][]string, error) {
@ -173,9 +201,7 @@ func getFileList(paths []string, filter string) (map[string][]string, error) {
} }
func cleanFilename(filename string) string { func cleanFilename(filename string) string {
filename = filename[:len(filename)-(len(filepath.Ext(filename))+3)] return filename[:len(filename)-(len(filepath.Ext(filename))+3)]
return filename
} }
func prepareDirectory(directory []string) []string { func prepareDirectory(directory []string) []string {
@ -189,10 +215,8 @@ func prepareDirectory(directory []string) []string {
if first == last { if first == last {
d := append([]string{}, directory[0]) d := append([]string{}, directory[0])
fmt.Printf("Appending %v to empty directory\n", d)
return d return d
} else { } else {
fmt.Printf("Returning directory as-is\n")
return directory return directory
} }
} }
@ -208,12 +232,11 @@ func prepareDirectories(m map[string][]string, successive string) []string {
i++ i++
} }
switch { if successive != "" {
case successive != "":
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {
directories = append(directories, prepareDirectory(m[keys[i]])...) directories = append(directories, prepareDirectory(m[keys[i]])...)
} }
default: } else {
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {
directories = append(directories, m[keys[i]]...) directories = append(directories, m[keys[i]]...)
} }
@ -228,15 +251,15 @@ func pickFile(args []string, filter, successive string) (string, error) {
return "", err return "", err
} }
rand.Seed(time.Now().UnixNano())
fileList := prepareDirectories(fileMap, successive) fileList := prepareDirectories(fileMap, successive)
rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(fileList), func(i, j int) { fileList[i], fileList[j] = fileList[j], fileList[i] }) rand.Shuffle(len(fileList), func(i, j int) { fileList[i], fileList[j] = fileList[j], fileList[i] })
for i := 0; i < len(fileList); i++ { for i := 0; i < len(fileList); i++ {
filePath := fileList[i] filePath := fileList[i]
isImage, err := checkIfImage(filePath) isImage, err := isImage(filePath)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var Version = "0.12.3" var Version = "0.12.4"
func init() { func init() {
rootCmd.AddCommand(versionCmd) rootCmd.AddCommand(versionCmd)

View File

@ -5,10 +5,8 @@ Copyright © 2022 Seednode <seednode@seedno.de>
package cmd package cmd
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -18,17 +16,26 @@ import (
"time" "time"
) )
const LOGDATE string = "2006-01-02T15:04:05.000000000-07:00" type appHandler func(http.ResponseWriter, *http.Request) error
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
}
}
const LOGDATE string = "2006-01-02T15:04:05.000000000-07:00"
const PREFIX string = "/src" const PREFIX string = "/src"
func stripQueryParam(inUrl string) string { func stripQueryParam(inUrl string) (string, error) {
u, err := url.Parse(inUrl) url, err := url.Parse(inUrl)
if err != nil { if err != nil {
panic(err) return "", err
} }
u.RawQuery = ""
return u.String() url.RawQuery = ""
return url.String(), nil
} }
func refererToUri(referer string) string { func refererToUri(referer string) string {
@ -69,42 +76,31 @@ func serveHtml(w http.ResponseWriter, r http.Request, filePath string) error {
} }
func serveStaticFile(w http.ResponseWriter, r http.Request, paths []string) error { func serveStaticFile(w http.ResponseWriter, r http.Request, paths []string) error {
prefixedFilePath, err := url.QueryUnescape(stripQueryParam(r.URL.Path)) strippedUrl, err := stripQueryParam(r.URL.Path)
if err != nil {
return err
}
prefixedFilePath, err := url.QueryUnescape(strippedUrl)
if err != nil { if err != nil {
return err return err
} }
filePath := strings.TrimPrefix(prefixedFilePath, PREFIX) filePath := strings.TrimPrefix(prefixedFilePath, PREFIX)
var matchesPrefix = false if !pathIsValid(filePath, paths) {
for i := 0; i < len(paths); i++ {
if strings.HasPrefix(filePath, paths[i]) {
matchesPrefix = true
}
}
if !matchesPrefix {
if Verbose {
fmt.Printf("%v Failed to serve file outside specified path(s): %v\n", time.Now().Format(LOGDATE), filePath)
}
http.NotFound(w, &r) http.NotFound(w, &r)
return nil
} }
_, err = os.Stat(filePath) exists, err := fileExists(filePath)
if errors.Is(err, os.ErrNotExist) { if err != nil {
if Verbose {
fmt.Printf("%v Failed to serve non-existent file: %v\n", time.Now().Format(LOGDATE), filePath)
}
http.NotFound(w, &r)
return nil
} else if !errors.Is(err, os.ErrNotExist) && err != nil {
return err return err
} }
if !exists {
http.NotFound(w, &r)
}
var startTime time.Time var startTime time.Time
if Verbose { if Verbose {
startTime = time.Now() startTime = time.Now()
@ -125,18 +121,23 @@ func serveStaticFile(w http.ResponseWriter, r http.Request, paths []string) erro
return nil return nil
} }
func serveStaticFileHandler(paths []string) http.HandlerFunc { func serveStaticFileHandler(paths []string) appHandler {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) error {
err := serveStaticFile(w, *r, paths) err := serveStaticFile(w, *r, paths)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
return nil
} }
} }
func serveHtmlHandler(paths []string) http.HandlerFunc { func serveHtmlHandler(paths []string) appHandler {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) error {
refererUri := stripQueryParam(refererToUri(r.Referer())) refererUri, err := stripQueryParam(refererToUri(r.Referer()))
if err != nil {
return err
}
filter := r.URL.Query().Get("f") filter := r.URL.Query().Get("f")
successive := r.URL.Query().Get("s") successive := r.URL.Query().Get("s")
@ -145,12 +146,12 @@ func serveHtmlHandler(paths []string) http.HandlerFunc {
case r.URL.Path == "/" && successive == "true" && refererUri != "": case r.URL.Path == "/" && successive == "true" && refererUri != "":
query, err := url.QueryUnescape(refererUri) query, err := url.QueryUnescape(refererUri)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
filePath, err := getNextFile(query) filePath, err := getNextFile(query)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
if filePath == "" { if filePath == "" {
@ -158,14 +159,14 @@ func serveHtmlHandler(paths []string) http.HandlerFunc {
switch { switch {
case err != nil && err == ErrNoImagesFound: case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r) http.NotFound(w, r)
return return nil
case err != nil: case err != nil:
log.Fatal(err) return err
} }
filePath, err = getFirstFile(filePath) filePath, err = getFirstFile(filePath)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
} }
@ -173,29 +174,27 @@ func serveHtmlHandler(paths []string) http.HandlerFunc {
http.Redirect(w, r, newUrl, http.StatusSeeOther) http.Redirect(w, r, newUrl, http.StatusSeeOther)
case r.URL.Path == "/" && successive == "true" && refererUri == "": case r.URL.Path == "/" && successive == "true" && refererUri == "":
filePath, err := pickFile(paths, filter, successive) filePath, err := pickFile(paths, filter, successive)
switch { if err != nil && err == ErrNoImagesFound {
case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r) http.NotFound(w, r)
return return nil
case err != nil: } else if err != nil {
log.Fatal(err) return err
} }
filePath, err = getFirstFile(filePath) filePath, err = getFirstFile(filePath)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, successive) newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, successive)
http.Redirect(w, r, newUrl, http.StatusSeeOther) http.Redirect(w, r, newUrl, http.StatusSeeOther)
case r.URL.Path == "/": case r.URL.Path == "/":
filePath, err := pickFile(paths, filter, successive) filePath, err := pickFile(paths, filter, successive)
switch { if err != nil && err == ErrNoImagesFound {
case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r) http.NotFound(w, r)
return return nil
case err != nil: } else if err != nil {
log.Fatal(err) return err
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, successive) newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, successive)
@ -203,42 +202,44 @@ func serveHtmlHandler(paths []string) http.HandlerFunc {
default: default:
filePath := r.URL.Path filePath := r.URL.Path
isImage, err := checkIfImage(filePath) image, err := isImage(filePath)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
if !isImage { if !image {
http.NotFound(w, r) http.NotFound(w, r)
} }
err = serveHtml(w, *r, filePath) err = serveHtml(w, *r, filePath)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
} }
return nil
} }
} }
func doNothing(http.ResponseWriter, *http.Request) {} func doNothing(http.ResponseWriter, *http.Request) {}
func ServePage(args []string) { func ServePage(args []string) error {
paths, err := normalizePaths(args) paths, err := normalizePaths(args)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
for _, i := range paths { for _, i := range paths {
fmt.Println("Paths: " + i) fmt.Println("Paths: " + i)
} }
http.HandleFunc("/", serveHtmlHandler(paths)) http.Handle("/", serveHtmlHandler(paths))
http.Handle(PREFIX+"/", http.StripPrefix(PREFIX, serveStaticFileHandler(paths))) http.Handle(PREFIX+"/", http.StripPrefix(PREFIX, serveStaticFileHandler(paths)))
http.HandleFunc("/favicon.ico", doNothing) http.HandleFunc("/favicon.ico", doNothing)
port := strconv.Itoa(Port) err = http.ListenAndServe(":"+strconv.Itoa(Port), nil)
err = http.ListenAndServe(":"+port, nil)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
return nil
} }