module Rack::Utils

def set_cookie_header(key, value)


# => "myname=myvalue; max-age=10"
set_cookie_header("myname", {value: "myvalue", max_age: 10})

# => "myname=myvalue"
set_cookie_header("myname", "myvalue")

cookie key name will not be url encoded (escaped). The default is +true+.
or not the cookie key is URL encoded. If explicitly set to +false+, the
An extra cookie attribute +escape_key+ can be provided to control whether

[RFC6265 Section 5.2](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2).
details about the interpretation of these fields, consult
of +Time+), +secure+, +http_only+, +same_site+ and +value+. For more
cookie attribute keys: +domain+, +max_age+, +expires+ (must be instance
If the cookie +value+ is an instance of +Hash+, it considers the following

instance of either +String+ or +Hash+.
for the +set-cookie+ header according to RFC6265. The +value+ may be an
Generate an encoded string using the provided +key+ and +value+ suitable

set_cookie_header(key, value) -> encoded string
:call-seq:
def set_cookie_header(key, value)
  case value
  when Hash
    key = escape(key) unless value[:escape_key] == false
    domain  = "; domain=#{value[:domain]}"   if value[:domain]
    path    = "; path=#{value[:path]}"       if value[:path]
    max_age = "; max-age=#{value[:max_age]}" if value[:max_age]
    expires = "; expires=#{value[:expires].httpdate}" if value[:expires]
    secure = "; secure"  if value[:secure]
    httponly = "; httponly" if (value.key?(:httponly) ? value[:httponly] : value[:http_only])
    same_site =
      case value[:same_site]
      when false, nil
        nil
      when :none, 'None', :None
        '; SameSite=None'
      when :lax, 'Lax', :Lax
        '; SameSite=Lax'
      when true, :strict, 'Strict', :Strict
        '; SameSite=Strict'
      else
        raise ArgumentError, "Invalid SameSite value: #{value[:same_site].inspect}"
      end
    value = value[:value]
  else
    key = escape(key)
  end
  value = [value] unless Array === value
  return "#{key}=#{value.map { |v| escape v }.join('&')}#{domain}" \
    "#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}"
end