Restructured code to hopefully be more readable
This commit is contained in:
parent
7fe46868c5
commit
919d1c2e8b
69
cmd/files.go
69
cmd/files.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
131
cmd/web.go
131
cmd/web.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue