class Cookiefilter

Constants

VERSION

Public Class Methods

delete(cookie) click to toggle source
# File lib/cookiefilter.rb, line 66
def delete(cookie)
  cookie[:options] = ' max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000;'
  cookie[:value] = 'unset'
  cookie
end
delete_cookies(blocked, limited) click to toggle source
# File lib/cookiefilter.rb, line 56
def delete_cookies(blocked, limited)
  blocked.each do |cookie|
    delete(cookie)
  end
  limited.each do |cookie|
    delete(cookie)
  end
  blocked + limited
end
filter_out_keepers(keepers) click to toggle source
# File lib/cookiefilter.rb, line 97
def filter_out_keepers(keepers)
  keepers.select { |keeper| keeper[:type] == :set }
end
filter_request_cookies(http_cookie) click to toggle source
# File lib/cookiefilter.rb, line 8
def filter_request_cookies(http_cookie)
  # Flag by replacing with cookie emoji(\u{1F36a}) as a token to identify
  # and invalidate cookies later on in is_valid_cookie!
  cookies = Cookiefilter::Utils.sanitize_utf8_string(
    http_cookie,
    Cookiefilter::Rules::DISALLOWED_CHARS,
    Cookiefilter::Rules::INVALID_TOKEN
  )
  cookies = Cookiefilter::Utils.parse_request_cookies(cookies)
  delete, keep = Cookiefilter.validate_request_cookies(cookies)
  header = Cookiefilter::Utils.construct_request_header(keep)
  { delete: delete, keep: keep, header: header.strip }
end
filter_response_cookies(host, response_header, response_cookies) click to toggle source
# File lib/cookiefilter.rb, line 22
def filter_response_cookies(host, response_header, response_cookies)
  keep, delete1 = response_cookies[:keep], response_cookies[:delete]
  cookies = Cookiefilter::Utils.parse_set_cookie_header(response_header)
  set, delete2 = Cookiefilter.validate_response_cookies(cookies)
  cookies = Cookiefilter.merge_keep_and_set(keep, set)
  cookies = Cookiefilter.sort_by_size(cookies)
  keepers, limited = Cookiefilter.maintain_limits(cookies)
  set = Cookiefilter.filter_out_keepers(keepers)
  deleted = Cookiefilter.delete_cookies(delete1 + delete2, limited)
  Cookiefilter::Utils.construct_response_header(host, deleted + set)
end
maintain_limits(sized_cookies, kept_large = [], limited = []) click to toggle source
# File lib/cookiefilter.rb, line 82
def maintain_limits(sized_cookies, kept_large = [], limited = [])
  if Cookiefilter.cookie_size_too_large?(kept_large, sized_cookies)
    removed = sized_cookies.shift if sized_cookies.count > 0
    removed = kept_large.shift if removed.nil?
    if removed[:sacred] && sized_cookies.count > 0
      kept_large.push(removed)
    else
      limited.push(removed)
    end
    return Cookiefilter.maintain_limits(sized_cookies, kept_large, limited)
  else
    return [kept_large + sized_cookies, limited]
  end
end
merge_keep_and_set(keep, set) click to toggle source
# File lib/cookiefilter.rb, line 72
def merge_keep_and_set(keep, set)
  keep.each do |keeper|
    keeper[:type] = :keep
  end
  set.each do |setter|
    setter[:type] = :set
  end
  return keep + set
end
new(app) click to toggle source
# File lib/cookiefilter.rb, line 152
def initialize(app)
  Cookiefilter::Validator.validate_safelist(Cookiefilter::Rules.safelist)
  @app = app
  @size = 0
end
sort_by_size(cookies) click to toggle source
# File lib/cookiefilter.rb, line 101
def sort_by_size(cookies)
  cookies.sort! do |a, b|
    b[:size] <=> a[:size]
  end
end
validate_request_cookies(cookies) click to toggle source
# File lib/cookiefilter.rb, line 34
def validate_request_cookies(cookies)
  cookies_to_keep = cookies.select do |cookie|
    is_valid_cookie!(cookie)
  end
  cookies_to_delete = cookies.reject do |cookie|
    is_valid_cookie!(cookie)
  end
  [cookies_to_delete, cookies_to_keep]
end
validate_response_cookies(cookies) click to toggle source
# File lib/cookiefilter.rb, line 44
def validate_response_cookies(cookies)
  cookies_to_set, cookies_to_delete = [], []
  cookies.each do |cookie|
    if is_valid_cookie!(cookie)
      cookies_to_set << cookie
    else
      cookies_to_delete << cookie
    end
  end
  [cookies_to_set, cookies_to_delete]
end

Public Instance Methods

call(env) click to toggle source

entry point, executes directly after initialize

# File lib/cookiefilter.rb, line 159
def call(env)
  result = Cookiefilter.filter_request_cookies(env['HTTP_COOKIE'])
  env['HTTP_COOKIE'] = result[:header]
  status, headers, body = @app.call(env)
  response = Rack::Response.new body, status, headers
  header = Cookiefilter.filter_response_cookies(
    env['HTTP_HOST'],
    response.header['Set-Cookie'],
    result
  )
  response.header['Set-Cookie'] = header
  response.finish
end