Class: CookieStore::CookieParser

Inherits:
Object
  • Object
show all
Includes:
StreamParser
Defined in:
lib/cookie_store/cookie_parser.rb

Constant Summary collapse

NUMERICAL_TIMEZONE =
/[-+]\d{4}\Z/

Instance Method Summary collapse

Instance Method Details

#normalize_attribute_value(key, value) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/cookie_store/cookie_parser.rb', line 74

def normalize_attribute_value(key, value)
  case key
  when :domain
    if value =~ CookieStore::Cookie::IPADDR
      value
    else
      # As per RFC2965 if a host name contains no dots, the effective host
      # name is that name with the string .local appended to it.
      value = "#{value}.local" if !value.include?('.')
      (value.start_with?('.') ? value : ".#{value}").downcase
    end
  when :expires
    byebug if $debug
    case value
    when /\w{3}, \d{2}-\w{3}-\d{2} /
      DateTime.strptime(value, '%a, %d-%b-%y %H:%M:%S %Z')
    when /\w{3}, \d{2}-\w{3}-\d{4} /
      DateTime.strptime(value, '%a, %d-%b-%Y %H:%M:%S %Z')
    when /\w{3}, \d{2} \w{3} \d{2} /
      DateTime.strptime(value, '%a, %d %b %y %H:%M:%S %Z')
    when /\w{3}, \d{2} \w{3} \d{4} /
      DateTime.strptime(value, '%a, %d %b %Y %H:%M:%S %Z')
    else
      DateTime.parse(value)
    end
  when :max_age
    value&.to_i
  when :ports
    value.split(',').map(&:to_i)
  when :version
    value.to_i
  else
    value
  end
end

#normalize_key(key) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cookie_store/cookie_parser.rb', line 61

def normalize_key(key)
  key = key.downcase.gsub('-','_')
  if key == 'port'
    :ports
  elsif key == 'httponly'
    :http_only
  elsif key == 'commenturl'
    :comment_url
  else
    key.to_sym
  end
end

#parse {|cookie| ... } ⇒ Object

Yields:

  • (cookie)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cookie_store/cookie_parser.rb', line 9

def parse
  cookie = {attributes: {}}
  
  @stack = [:cookie_name]
  while !eos?
    case @stack.last
    when :cookie_name
      scan_until(/\s*=\s*/)
      if match == '='
        @stack << :cookie_value
        cookie[:key] = pre_match
      end
    when :cookie_value
      scan_until(/\s*(['";]\s*|\Z)/)
      if match.strip == '"' || match.strip == "'"
        cookie[:value] = quoted_value(match.strip)
        @stack.pop
        @stack << :cookie_attributes
      elsif match
        cookie[:value] = pre_match
        @stack.pop
        @stack << :cookie_attributes
      end
    when :cookie_attributes
      # RFC 2109 4.1, Attributes (names) are case-insensitive
      scan_until(/[,=;]\s*/)
      if match&.start_with?('=')
        key = normalize_key(pre_match)
        scan_until(key == :expires ? /\s*((?<!\w{3}),|['";])\s*/ : /\s*(['";,]\s*|\Z)/)
        if match =~ /["']\s*\Z/
          cookie[:attributes][key] = normalize_attribute_value(key, quoted_value(match.strip))
        elsif match =~ /,\s*\Z/
          cookie[:attributes][key] = normalize_attribute_value(key, pre_match)
          yield(cookie)
          cookie = {attributes: {}}
          @stack.pop
        else
          cookie[:attributes][key] = normalize_attribute_value(key, pre_match)
        end
      elsif match&.start_with?(',')
        yield(cookie)
        cookie = {attributes: {}}
        @stack.pop
      else
        cookie[:attributes][normalize_key(pre_match)] = true
      end
    end
  end
  
  yield(cookie)
end