fix(sticky): check cookie expiration in Select method
- Fix Select to check if cookie is expired before routing - Add TestStickySession_ExpiredCookie test - Expired cookies now trigger fallback + new cookie set
This commit is contained in:
parent
66752a47f0
commit
360fd0da9d
@ -100,8 +100,8 @@ func (s *StickySession) Select(ctx *fasthttp.RequestCtx, targets []*Target) *Tar
|
|||||||
// 检查现有 cookie
|
// 检查现有 cookie
|
||||||
cookieValue := ctx.Request.Header.Cookie(s.config.Name)
|
cookieValue := ctx.Request.Header.Cookie(s.config.Name)
|
||||||
if len(cookieValue) > 0 {
|
if len(cookieValue) > 0 {
|
||||||
decodedURL, _, ok := decodeStickyCookie(string(cookieValue))
|
decodedURL, expires, ok := decodeStickyCookie(string(cookieValue))
|
||||||
if ok && decodedURL != "" {
|
if ok && decodedURL != "" && expires.After(time.Now()) {
|
||||||
// 查找对应的目标
|
// 查找对应的目标
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
if target.URL == decodedURL && target.IsAvailable() {
|
if target.URL == decodedURL && target.IsAvailable() {
|
||||||
|
|||||||
@ -238,6 +238,46 @@ func TestStickySession_Concurrent(t *testing.T) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestStickySession_ExpiredCookie 测试过期 cookie 会导致回退到 fallback。
|
||||||
|
func TestStickySession_ExpiredCookie(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
fallback := NewRoundRobin()
|
||||||
|
config := DefaultStickyConfig()
|
||||||
|
config.Enabled = true
|
||||||
|
config.Expires = -time.Hour // Negative = already expired
|
||||||
|
|
||||||
|
sticky := NewStickySession(config, fallback)
|
||||||
|
sticky.Start()
|
||||||
|
defer sticky.Stop()
|
||||||
|
|
||||||
|
// Make backend1 unavailable so we know for sure fallback picks backend2
|
||||||
|
targets := []*Target{
|
||||||
|
createHealthyTarget("http://backend1:8080", false),
|
||||||
|
createHealthyTarget("http://backend2:8080", true),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an expired cookie manually
|
||||||
|
expiredCookie := encodeStickyCookie("http://backend1:8080", time.Now().Add(-time.Hour))
|
||||||
|
|
||||||
|
ctx := &fasthttp.RequestCtx{}
|
||||||
|
ctx.Request.Header.SetCookie(config.Name, expiredCookie)
|
||||||
|
|
||||||
|
// Should fallback because cookie is expired (and even if not, backend1 is unavailable)
|
||||||
|
selected := sticky.Select(ctx, targets)
|
||||||
|
if selected == nil {
|
||||||
|
t.Fatal("expected a target")
|
||||||
|
}
|
||||||
|
// Should not route to backend1 because cookie expired / unavailable
|
||||||
|
if selected.URL == "http://backend1:8080" {
|
||||||
|
t.Error("should not route using expired cookie")
|
||||||
|
}
|
||||||
|
// Should set a new cookie
|
||||||
|
newCookie := ctx.Response.Header.PeekCookie(config.Name)
|
||||||
|
if len(newCookie) == 0 {
|
||||||
|
t.Error("expected new cookie to be set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestStickySession_SelectExcluding 测试排除选择委托给 fallback。
|
// TestStickySession_SelectExcluding 测试排除选择委托给 fallback。
|
||||||
func TestStickySession_SelectExcluding(t *testing.T) {
|
func TestStickySession_SelectExcluding(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user