️ slices.SortFunc for upstreams

This commit is contained in:
Kawin Viriyaprasopsook 2024-07-22 15:26:58 +07:00
parent 02ff288280
commit 6bfcb2e1f5
2 changed files with 40 additions and 32 deletions

View File

@ -41,12 +41,12 @@ func SendOK(w http.ResponseWriter) {
// Get GET parameter // Get GET parameter
func GetPara(r *http.Request, key string) (string, error) { func GetPara(r *http.Request, key string) (string, error) {
keys, ok := r.URL.Query()[key] // Get first value from the URL query
if !ok || len(keys[0]) < 1 { value := r.URL.Query().Get(key)
if len(value) == 0 {
return "", errors.New("invalid " + key + " given") return "", errors.New("invalid " + key + " given")
} else {
return keys[0], nil
} }
return value, nil
} }
// Get GET paramter as boolean, accept 1 or true // Get GET paramter as boolean, accept 1 or true
@ -56,26 +56,29 @@ func GetBool(r *http.Request, key string) (bool, error) {
return false, err return false, err
} }
x = strings.TrimSpace(x) // Convert to lowercase and trim spaces just once to compare
switch strings.ToLower(strings.TrimSpace(x)) {
if x == "1" || strings.ToLower(x) == "true" || strings.ToLower(x) == "on" { case "1", "true", "on":
return true, nil return true, nil
} else if x == "0" || strings.ToLower(x) == "false" || strings.ToLower(x) == "off" { case "0", "false", "off":
return false, nil return false, nil
} }
return false, errors.New("invalid boolean given") return false, errors.New("invalid boolean given")
} }
// Get POST paramter // Get POST parameter
func PostPara(r *http.Request, key string) (string, error) { func PostPara(r *http.Request, key string) (string, error) {
r.ParseForm() // Try to parse the form
x := r.Form.Get(key) if err := r.ParseForm(); err != nil {
if x == "" { return "", err
return "", errors.New("invalid " + key + " given")
} else {
return x, nil
} }
// Get first value from the form
x := r.Form.Get(key)
if len(x) == 0 {
return "", errors.New("invalid " + key + " given")
}
return x, nil
} }
// Get POST paramter as boolean, accept 1 or true // Get POST paramter as boolean, accept 1 or true
@ -85,11 +88,11 @@ func PostBool(r *http.Request, key string) (bool, error) {
return false, err return false, err
} }
x = strings.TrimSpace(x) // Convert to lowercase and trim spaces just once to compare
switch strings.ToLower(strings.TrimSpace(x)) {
if x == "1" || strings.ToLower(x) == "true" || strings.ToLower(x) == "on" { case "1", "true", "on":
return true, nil return true, nil
} else if x == "0" || strings.ToLower(x) == "false" || strings.ToLower(x) == "off" { case "0", "false", "off":
return false, nil return false, nil
} }
@ -114,14 +117,19 @@ func PostInt(r *http.Request, key string) (int, error) {
func FileExists(filename string) bool { func FileExists(filename string) bool {
_, err := os.Stat(filename) _, err := os.Stat(filename)
if os.IsNotExist(err) { if err == nil {
// File exists
return true
} else if errors.Is(err, os.ErrNotExist) {
// File does not exist
return false return false
} }
return true // Some other error
return false
} }
func IsDir(path string) bool { func IsDir(path string) bool {
if FileExists(path) == false { if !FileExists(path) {
return false return false
} }
fi, err := os.Stat(path) fi, err := os.Stat(path)

View File

@ -1,9 +1,10 @@
package main package main
import ( import (
"cmp"
"encoding/json" "encoding/json"
"net/http" "net/http"
"sort" "slices"
"strings" "strings"
"imuslab.com/zoraxy/mod/dynamicproxy/loadbalance" "imuslab.com/zoraxy/mod/dynamicproxy/loadbalance"
@ -33,19 +34,18 @@ func ReverseProxyUpstreamList(w http.ResponseWriter, r *http.Request) {
activeUpstreams := targetEndpoint.ActiveOrigins activeUpstreams := targetEndpoint.ActiveOrigins
inactiveUpstreams := targetEndpoint.InactiveOrigins inactiveUpstreams := targetEndpoint.InactiveOrigins
// Sort the upstreams slice by weight, then by origin domain alphabetically slices.SortFunc(activeUpstreams, func(i, j *loadbalance.Upstream) int {
sort.Slice(activeUpstreams, func(i, j int) bool { if i.Weight != j.Weight {
if activeUpstreams[i].Weight != activeUpstreams[j].Weight { return cmp.Compare(j.Weight, i.Weight)
return activeUpstreams[i].Weight > activeUpstreams[j].Weight
} }
return activeUpstreams[i].OriginIpOrDomain < activeUpstreams[j].OriginIpOrDomain return cmp.Compare(i.OriginIpOrDomain, j.OriginIpOrDomain)
}) })
sort.Slice(inactiveUpstreams, func(i, j int) bool { slices.SortFunc(inactiveUpstreams, func(i, j *loadbalance.Upstream) int {
if inactiveUpstreams[i].Weight != inactiveUpstreams[j].Weight { if i.Weight != j.Weight {
return inactiveUpstreams[i].Weight > inactiveUpstreams[j].Weight return cmp.Compare(j.Weight, i.Weight)
} }
return inactiveUpstreams[i].OriginIpOrDomain < inactiveUpstreams[j].OriginIpOrDomain return cmp.Compare(i.OriginIpOrDomain, j.OriginIpOrDomain)
}) })
type UpstreamCombinedList struct { type UpstreamCombinedList struct {