Files

52 lines
1.3 KiB
Go

package loadbalancer
import (
"encoding/hex"
"net/http"
"strings"
"time"
"unsafe"
"github.com/bytedance/gopkg/util/xxhash3"
"github.com/yusing/godoxy/internal/types"
)
func hashServerKey(key string) string {
h := xxhash3.HashString(key)
as8bytes := *(*[8]byte)(unsafe.Pointer(&h))
return hex.EncodeToString(as8bytes[:])
}
// getStickyServer extracts the sticky session cookie and returns the corresponding server
func getStickyServer(r *http.Request, srvs []types.LoadBalancerServer) types.LoadBalancerServer {
cookie, err := r.Cookie("godoxy_lb_sticky")
if err != nil {
return nil
}
serverKeyHash := cookie.Value
for _, srv := range srvs {
if hashServerKey(srv.Key()) == serverKeyHash {
return srv
}
}
return nil
}
// setStickyCookie sets a cookie to maintain sticky session with a specific server
func setStickyCookie(rw http.ResponseWriter, r *http.Request, srv types.LoadBalancerServer, maxAge time.Duration) {
http.SetCookie(rw, &http.Cookie{
Name: "godoxy_lb_sticky",
Value: hashServerKey(srv.Key()),
Path: "/",
MaxAge: int(maxAge.Seconds()),
SameSite: http.SameSiteLaxMode,
HttpOnly: true,
Secure: isSecure(r),
})
}
func isSecure(r *http.Request) bool {
return r.TLS != nil || strings.EqualFold(r.Header.Get("X-Forwarded-Proto"), "https")
}