Added basic input verification for sortOrder/refreshInterval
This commit is contained in:
parent
28af94cba3
commit
ea4b1be5c3
|
@ -50,7 +50,7 @@ Note: These patterns require sequentially-numbered files matching the following
|
||||||
|
|
||||||
## Refresh
|
## Refresh
|
||||||
|
|
||||||
If a `refresh=<time in seconds>` query parameter is provided, the page will reload after that interval.
|
If a non-zero `refresh=<time in seconds>` query parameter is provided, the page will reload after that interval.
|
||||||
|
|
||||||
This can be used to generate a sort of slideshow of images.
|
This can be used to generate a sort of slideshow of images.
|
||||||
|
|
||||||
|
|
13
cmd/files.go
13
cmd/files.go
|
@ -15,7 +15,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -212,13 +211,13 @@ func appendPaths(path string, files *Files, filters *Filters, stats *Stats) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNewFile(paths []string, filters *Filters, sortOrder string, re regexp.Regexp, fileCache *[]string) (string, error) {
|
func getNewFile(paths []string, filters *Filters, sortOrder string, regexes *Regexes, fileCache *[]string) (string, error) {
|
||||||
filePath, err := pickFile(paths, filters, sortOrder, fileCache)
|
filePath, err := pickFile(paths, filters, sortOrder, fileCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := splitPath(filePath, re)
|
path, err := splitPath(filePath, regexes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -256,8 +255,8 @@ func getNewFile(paths []string, filters *Filters, sortOrder string, re regexp.Re
|
||||||
return filePath, nil
|
return filePath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNextFile(filePath, sortOrder string, re regexp.Regexp) (string, error) {
|
func getNextFile(filePath, sortOrder string, regexes *Regexes) (string, error) {
|
||||||
path, err := splitPath(filePath, re)
|
path, err := splitPath(filePath, regexes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -279,11 +278,11 @@ func getNextFile(filePath, sortOrder string, re regexp.Regexp) (string, error) {
|
||||||
return fileName, err
|
return fileName, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitPath(path string, re regexp.Regexp) (*Path, error) {
|
func splitPath(path string, regexes *Regexes) (*Path, error) {
|
||||||
p := Path{}
|
p := Path{}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
split := re.FindAllStringSubmatch(path, -1)
|
split := regexes.Filename.FindAllStringSubmatch(path, -1)
|
||||||
|
|
||||||
if len(split) < 1 || len(split[0]) < 3 {
|
if len(split) < 1 || len(split[0]) < 3 {
|
||||||
return &Path{}, nil
|
return &Path{}, nil
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "0.25.2"
|
var Version = "0.25.3"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
|
|
74
cmd/web.go
74
cmd/web.go
|
@ -28,6 +28,11 @@ const (
|
||||||
RedirectStatusCode int = http.StatusSeeOther
|
RedirectStatusCode int = http.StatusSeeOther
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Regexes struct {
|
||||||
|
Alphanumeric *regexp.Regexp
|
||||||
|
Filename *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
type Filters struct {
|
type Filters struct {
|
||||||
Includes []string
|
Includes []string
|
||||||
Excludes []string
|
Excludes []string
|
||||||
|
@ -81,7 +86,31 @@ func notFound(w http.ResponseWriter, r *http.Request, filePath string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitQueryParams(query string) []string {
|
func getRefreshInterval(r *http.Request) string {
|
||||||
|
refreshInterval := r.URL.Query().Get("refresh")
|
||||||
|
|
||||||
|
if refreshInterval == "" {
|
||||||
|
refreshInterval = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
num, err := strconv.Atoi(refreshInterval)
|
||||||
|
if err != nil || num < 0 {
|
||||||
|
refreshInterval = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
return refreshInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSortOrder(r *http.Request) string {
|
||||||
|
sortOrder := r.URL.Query().Get("sort")
|
||||||
|
if !(sortOrder == "asc" || sortOrder == "desc") {
|
||||||
|
sortOrder = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitQueryParams(query string, regexes *Regexes) []string {
|
||||||
if query == "" {
|
if query == "" {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +118,12 @@ func splitQueryParams(query string) []string {
|
||||||
params := strings.Split(query, ",")
|
params := strings.Split(query, ",")
|
||||||
|
|
||||||
for i := 0; i < len(params); i++ {
|
for i := 0; i < len(params); i++ {
|
||||||
|
isAlphanumeric := regexes.Alphanumeric.MatchString(params[i])
|
||||||
|
|
||||||
|
if isAlphanumeric {
|
||||||
params[i] = strings.ToLower(params[i])
|
params[i] = strings.ToLower(params[i])
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
@ -179,12 +212,11 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath string, dimensio
|
||||||
|
|
||||||
w.Header().Add("Content-Type", "text/html")
|
w.Header().Add("Content-Type", "text/html")
|
||||||
|
|
||||||
refreshInterval := r.URL.Query().Get("refresh")
|
refreshInterval := getRefreshInterval(r)
|
||||||
if refreshInterval == "" {
|
|
||||||
refreshInterval = "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
queryParams := generateQueryParams(filters, r.URL.Query().Get("sort"), refreshInterval)
|
sortOrder := getSortOrder(r)
|
||||||
|
|
||||||
|
queryParams := generateQueryParams(filters, sortOrder, refreshInterval)
|
||||||
|
|
||||||
var htmlBody strings.Builder
|
var htmlBody strings.Builder
|
||||||
htmlBody.WriteString(`<!DOCTYPE html><html lang="en"><head>`)
|
htmlBody.WriteString(`<!DOCTYPE html><html lang="en"><head>`)
|
||||||
|
@ -281,7 +313,7 @@ func serveStaticFileHandler(paths []string) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) http.HandlerFunc {
|
func serveHtmlHandler(paths []string, regexes *Regexes, fileCache *[]string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
refererUri, err := stripQueryParams(refererToUri(r.Referer()))
|
refererUri, err := stripQueryParams(refererToUri(r.Referer()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -289,29 +321,26 @@ func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) htt
|
||||||
}
|
}
|
||||||
|
|
||||||
filters := Filters{}
|
filters := Filters{}
|
||||||
filters.Includes = splitQueryParams(r.URL.Query().Get("include"))
|
filters.Includes = splitQueryParams(r.URL.Query().Get("include"), regexes)
|
||||||
filters.Excludes = splitQueryParams(r.URL.Query().Get("exclude"))
|
filters.Excludes = splitQueryParams(r.URL.Query().Get("exclude"), regexes)
|
||||||
|
|
||||||
sortOrder := r.URL.Query().Get("sort")
|
sortOrder := getSortOrder(r)
|
||||||
|
|
||||||
refreshInterval := r.URL.Query().Get("refresh")
|
refreshInterval := getRefreshInterval(r)
|
||||||
if refreshInterval == "" {
|
|
||||||
refreshInterval = "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == "/" {
|
||||||
var filePath string
|
var filePath string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if refererUri != "" {
|
if refererUri != "" {
|
||||||
filePath, err = getNextFile(refererUri, sortOrder, re)
|
filePath, err = getNextFile(refererUri, sortOrder, regexes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if filePath == "" {
|
if filePath == "" {
|
||||||
filePath, err = getNewFile(paths, &filters, sortOrder, re, fileCache)
|
filePath, err = getNewFile(paths, &filters, sortOrder, regexes, fileCache)
|
||||||
switch {
|
switch {
|
||||||
case err != nil && err == ErrNoImagesFound:
|
case err != nil && err == ErrNoImagesFound:
|
||||||
notFound(w, r, filePath)
|
notFound(w, r, filePath)
|
||||||
|
@ -372,6 +401,15 @@ func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) htt
|
||||||
|
|
||||||
func doNothing(http.ResponseWriter, *http.Request) {}
|
func doNothing(http.ResponseWriter, *http.Request) {}
|
||||||
|
|
||||||
|
func generateRegularExpressions() *Regexes {
|
||||||
|
r := Regexes{}
|
||||||
|
|
||||||
|
r.Filename = regexp.MustCompile(`(.+)([0-9]{3})(\..+)`)
|
||||||
|
r.Alphanumeric = regexp.MustCompile(`^[a-zA-Z0-9]*$`)
|
||||||
|
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
func ServePage(args []string) error {
|
func ServePage(args []string) error {
|
||||||
fmt.Printf("roulette v%v\n\n", Version)
|
fmt.Printf("roulette v%v\n\n", Version)
|
||||||
|
|
||||||
|
@ -380,13 +418,13 @@ func ServePage(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
re := regexp.MustCompile(`(.+)([0-9]{3})(\..+)`)
|
regexes := generateRegularExpressions()
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
fileCache := []string{}
|
fileCache := []string{}
|
||||||
|
|
||||||
http.Handle("/", serveHtmlHandler(paths, *re, &fileCache))
|
http.Handle("/", serveHtmlHandler(paths, regexes, &fileCache))
|
||||||
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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue