class ActionDispatch::Cookies::CookieJar

:nodoc:

def self.build(req, cookies)

def self.build(req, cookies)
  jar = new(req)
  jar.update(cookies)
  jar
end

def [](name)

Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
def [](name)
  @cookies[name.to_s]
end

def []=(name, options)

value or a hash of options as documented above.
Sets the cookie named +name+. The second argument may be the cookie's
def []=(name, options)
  if options.is_a?(Hash)
    options.symbolize_keys!
    value = options[:value]
  else
    value = options
    options = { value: value }
  end
  handle_options(options)
  if @cookies[name.to_s] != value || options[:expires]
    @cookies[name.to_s] = value
    @set_cookies[name.to_s] = options
    @delete_cookies.delete(name.to_s)
  end
  value
end

def clear(options = {})

Removes all cookies on the client machine by calling delete for each cookie.
def clear(options = {})
  @cookies.each_key { |k| delete(k, options) }
end

def commit!

def commit!
  @committed = true
  @set_cookies.freeze
  @delete_cookies.freeze
end

def committed?; @committed; end

def committed?; @committed; end

def delete(name, options = {})

Returns the value of the cookie, or +nil+ if the cookie does not exist.

an options hash to delete cookies with extra data such as a :path.
and the expiration date in the past. Like []=, you can pass in
Removes the cookie on the client machine by setting the value to an empty string
def delete(name, options = {})
  return unless @cookies.has_key? name.to_s
  options.symbolize_keys!
  handle_options(options)
  value = @cookies.delete(name.to_s)
  @delete_cookies[name.to_s] = options
  value
end

def deleted?(name, options = {})

deletion applies to a specific :path, :domain etc.
Like []=, you can pass in an options hash to test if a
Whether the given cookie is to be deleted by this CookieJar.
def deleted?(name, options = {})
  options.symbolize_keys!
  handle_options(options)
  @delete_cookies[name.to_s] == options
end

def each(&block)

def each(&block)
  @cookies.each(&block)
end

def escape(string)

def escape(string)
  ::Rack::Utils.escape(string)
end

def fetch(name, *args, &block)

def fetch(name, *args, &block)
  @cookies.fetch(name.to_s, *args, &block)
end

def handle_options(options)

def handle_options(options)
  if options[:expires].respond_to?(:from_now)
    options[:expires] = options[:expires].from_now
  end
  options[:path]      ||= "/"
  unless options.key?(:same_site)
    options[:same_site] = request.cookies_same_site_protection
  end
  if options[:domain] == :all || options[:domain] == "all"
    cookie_domain = ""
    dot_splitted_host = request.host.split(".", -1)
    # Case where request.host is not an IP address or it's an invalid domain
    # (ip confirms to the domain structure we expect so we explicitly check for ip)
    if request.host.match?(/^[\d.]+$/) || dot_splitted_host.include?("") || dot_splitted_host.length == 1
      options[:domain] = nil
      return
    end
    # If there is a provided tld length then we use it otherwise default domain.
    if options[:tld_length].present?
      # Case where the tld_length provided is valid
      if dot_splitted_host.length >= options[:tld_length]
        cookie_domain = dot_splitted_host.last(options[:tld_length]).join(".")
      end
    # Case where tld_length is not provided
    else
      # Regular TLDs
      if !(/\.[^.]{2,3}\.[^.]{2}\z/.match?(request.host))
        cookie_domain = dot_splitted_host.last(2).join(".")
      # **.**, ***.** style TLDs like co.uk and com.au
      else
        cookie_domain = dot_splitted_host.last(3).join(".")
      end
    end
    options[:domain] = if cookie_domain.present?
      cookie_domain
    end
  elsif options[:domain].is_a? Array
    # If host matches one of the supplied domains.
    options[:domain] = options[:domain].find do |domain|
      domain = domain.delete_prefix(".")
      request.host == domain || request.host.end_with?(".#{domain}")
    end
  elsif options[:domain].respond_to?(:call)
    options[:domain] = options[:domain].call(request)
  end
end

def initialize(request)

def initialize(request)
  @set_cookies = {}
  @delete_cookies = {}
  @request = request
  @cookies = {}
  @committed = false
end

def key?(name)

def key?(name)
  @cookies.key?(name.to_s)
end

def to_header

def to_header
  @cookies.map { |k, v| "#{escape(k)}=#{escape(v)}" }.join "; "
end

def update(other_hash)

def update(other_hash)
  @cookies.update other_hash.stringify_keys
  self
end

def update_cookies_from_jar

def update_cookies_from_jar
  request_jar = @request.cookie_jar.instance_variable_get(:@cookies)
  set_cookies = request_jar.reject { |k, _| @delete_cookies.key?(k) || @set_cookies.key?(k) }
  @cookies.update set_cookies if set_cookies
end

def write(response)

def write(response)
  @set_cookies.each do |name, value|
    if write_cookie?(value)
      response.set_cookie(name, value)
    end
  end
  @delete_cookies.each do |name, value|
    response.delete_cookie(name, value)
  end
end

def write_cookie?(cookie)

def write_cookie?(cookie)
  request.ssl? || !cookie[:secure] || always_write_cookie || request.host.end_with?(".onion")
end