2023-09-11 17:09:08 +00:00
|
|
|
/*
|
|
|
|
Copyright © 2023 Seednode <seednode@seedno.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2023-09-12 18:06:45 +00:00
|
|
|
func refreshInterval(r *http.Request) (int64, string) {
|
2023-09-14 05:01:50 +00:00
|
|
|
interval := r.URL.Query().Get("refresh")
|
2023-09-11 17:09:08 +00:00
|
|
|
|
|
|
|
duration, err := time.ParseDuration(interval)
|
|
|
|
|
|
|
|
switch {
|
2023-09-14 05:07:54 +00:00
|
|
|
case err != nil || duration == 0 || !Refresh:
|
2023-09-11 17:09:08 +00:00
|
|
|
return 0, "0ms"
|
|
|
|
case duration < 500*time.Millisecond:
|
|
|
|
return 500, "500ms"
|
|
|
|
default:
|
|
|
|
return duration.Milliseconds(), interval
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func sortOrder(r *http.Request) string {
|
2023-09-11 17:09:08 +00:00
|
|
|
sortOrder := r.URL.Query().Get("sort")
|
|
|
|
if sortOrder == "asc" || sortOrder == "desc" {
|
|
|
|
return sortOrder
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func splitQueryParams(query string, regexes *regexes) []string {
|
2023-09-11 17:09:08 +00:00
|
|
|
results := []string{}
|
|
|
|
|
|
|
|
if query == "" {
|
|
|
|
return results
|
|
|
|
}
|
|
|
|
|
|
|
|
params := strings.Split(query, ",")
|
|
|
|
|
|
|
|
for i := 0; i < len(params); i++ {
|
2023-09-25 16:15:49 +00:00
|
|
|
switch {
|
|
|
|
case regexes.alphanumeric.MatchString(params[i]) && CaseSensitive:
|
|
|
|
results = append(results, params[i])
|
2023-09-25 22:08:40 +00:00
|
|
|
case regexes.alphanumeric.MatchString(params[i]):
|
|
|
|
results = append(results, strings.ToLower(params[i]))
|
2023-09-11 17:09:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return results
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func generateQueryParams(filters *filters, sortOrder, refreshInterval string) string {
|
2023-09-11 17:09:08 +00:00
|
|
|
var hasParams bool
|
|
|
|
|
|
|
|
var queryParams strings.Builder
|
|
|
|
|
|
|
|
queryParams.WriteString("?")
|
|
|
|
|
2023-09-12 18:06:45 +00:00
|
|
|
if Filtering {
|
2023-09-11 17:09:08 +00:00
|
|
|
queryParams.WriteString("include=")
|
2023-09-13 14:26:15 +00:00
|
|
|
if filters.hasIncludes() {
|
|
|
|
queryParams.WriteString(filters.includes())
|
2023-09-11 17:09:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
queryParams.WriteString("&exclude=")
|
2023-09-13 14:26:15 +00:00
|
|
|
if filters.hasExcludes() {
|
|
|
|
queryParams.WriteString(filters.excludes())
|
2023-09-11 17:09:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hasParams = true
|
|
|
|
}
|
|
|
|
|
2023-09-12 18:06:45 +00:00
|
|
|
if Sorting {
|
2023-09-11 17:09:08 +00:00
|
|
|
if hasParams {
|
|
|
|
queryParams.WriteString("&")
|
|
|
|
}
|
|
|
|
|
|
|
|
queryParams.WriteString(fmt.Sprintf("sort=%s", sortOrder))
|
|
|
|
|
|
|
|
hasParams = true
|
|
|
|
}
|
|
|
|
|
2023-09-14 05:07:54 +00:00
|
|
|
if Refresh {
|
2023-09-14 05:01:50 +00:00
|
|
|
if hasParams {
|
|
|
|
queryParams.WriteString("&")
|
|
|
|
}
|
|
|
|
queryParams.WriteString(fmt.Sprintf("refresh=%s", refreshInterval))
|
|
|
|
|
|
|
|
hasParams = true
|
|
|
|
}
|
|
|
|
|
2023-09-11 17:09:08 +00:00
|
|
|
if hasParams {
|
2023-09-14 05:01:50 +00:00
|
|
|
return queryParams.String()
|
2023-09-11 17:09:08 +00:00
|
|
|
}
|
|
|
|
|
2023-09-14 05:01:50 +00:00
|
|
|
return ""
|
2023-09-11 17:09:08 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func stripQueryParams(request string) (string, error) {
|
|
|
|
uri, err := url.Parse(request)
|
2023-09-11 17:09:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
uri.RawQuery = ""
|
|
|
|
|
|
|
|
escapedUri, err := url.QueryUnescape(uri.String())
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
return strings.TrimPrefix(escapedUri, "/"), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return escapedUri, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateFileUri(path string) string {
|
|
|
|
var uri strings.Builder
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
uri.WriteString(sourcePrefix)
|
2023-09-11 17:09:08 +00:00
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
uri.WriteString(`/`)
|
|
|
|
}
|
|
|
|
uri.WriteString(path)
|
|
|
|
|
|
|
|
return uri.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func refererToUri(referer string) string {
|
|
|
|
parts := strings.SplitAfterN(referer, "/", 4)
|
|
|
|
|
|
|
|
if len(parts) < 4 {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return "/" + parts[3]
|
|
|
|
}
|
|
|
|
|
|
|
|
func realIP(r *http.Request) string {
|
|
|
|
remoteAddr := strings.SplitAfter(r.RemoteAddr, ":")
|
|
|
|
|
|
|
|
if len(remoteAddr) < 1 {
|
|
|
|
return r.RemoteAddr
|
|
|
|
}
|
|
|
|
|
|
|
|
remotePort := remoteAddr[len(remoteAddr)-1]
|
|
|
|
|
|
|
|
cfIP := r.Header.Get("Cf-Connecting-Ip")
|
|
|
|
xRealIp := r.Header.Get("X-Real-Ip")
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case cfIP != "":
|
|
|
|
return cfIP + ":" + remotePort
|
|
|
|
case xRealIp != "":
|
|
|
|
return xRealIp + ":" + remotePort
|
|
|
|
default:
|
|
|
|
return r.RemoteAddr
|
|
|
|
}
|
|
|
|
}
|