reverseproxy: add Max-Age option to sticky cookie (#6398)

* reverseproxy: add Max-Age option to sticky cookie

* Update selectionpolicies.go

Co-authored-by: Francis Lavoie <lavofr@gmail.com>

* Update selectionpolicies.go

Co-authored-by: Francis Lavoie <lavofr@gmail.com>

---------

Co-authored-by: Francis Lavoie <lavofr@gmail.com>
This commit is contained in:
Jason Yuan 2024-06-15 09:50:31 -04:00 committed by GitHub
parent aca4002fd8
commit fab6375a8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 25 additions and 0 deletions

View File

@ -26,6 +26,7 @@ import (
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/cespare/xxhash/v2"
@ -613,6 +614,8 @@ type CookieHashSelection struct {
Name string `json:"name,omitempty"`
// Secret to hash (Hmac256) chosen upstream in cookie
Secret string `json:"secret,omitempty"`
// The cookie's Max-Age before it expires. Default is no expiry.
MaxAge caddy.Duration `json:"max_age,omitempty"`
// The fallback policy to use if the cookie is not present. Defaults to `random`.
FallbackRaw json.RawMessage `json:"fallback,omitempty" caddy:"namespace=http.reverse_proxy.selection_policies inline_key=policy"`
@ -671,6 +674,9 @@ func (s CookieHashSelection) Select(pool UpstreamPool, req *http.Request, w http
cookie.Secure = true
cookie.SameSite = http.SameSiteNoneMode
}
if s.MaxAge > 0 {
cookie.MaxAge = int(time.Duration(s.MaxAge).Seconds())
}
http.SetCookie(w, cookie)
return upstream
}
@ -699,6 +705,7 @@ func (s CookieHashSelection) Select(pool UpstreamPool, req *http.Request, w http
//
// lb_policy cookie [<name> [<secret>]] {
// fallback <policy>
// max_age <duration>
// }
//
// By default name is `lb`
@ -728,6 +735,24 @@ func (s *CookieHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
return err
}
s.FallbackRaw = mod
case "max_age":
if !d.NextArg() {
return d.ArgErr()
}
if s.MaxAge != 0 {
return d.Err("cookie max_age already specified")
}
maxAge, err := caddy.ParseDuration(d.Val())
if err != nil {
return d.Errf("invalid duration: %s", d.Val())
}
if maxAge <= 0 {
return d.Errf("invalid duration: %s, max_age should be non-zero and positive", d.Val())
}
if d.NextArg() {
return d.ArgErr()
}
s.MaxAge = caddy.Duration(maxAge)
default:
return d.Errf("unrecognized option '%s'", d.Val())
}