Constants
RE_BAD_CHAR | = | /([\x00-\x20\x7F",;\\])/.freeze | ||
RE_COOKIE_COMMA | = | /,(?=#{RE_WSP}?#{RE_NAME}=)/.freeze |
A pattern that matches the comma in a (typically date) value. |
|
RE_NAME | = | /(?!#{RE_WSP})[^,;\\"=]*/.freeze |
A pattern that matches a cookie name or attribute name which may be empty, capturing trailing whitespace. |
|
RE_WSP | = | /[ \t]+/.freeze |
Whitespace. |
Public Instance methods
call(set_cookie)
[show source]
# File lib/httpx/plugins/cookies/set_cookie_parser.rb 75 def call(set_cookie) 76 scanner = StringScanner.new(set_cookie) 77 78 # RFC 6265 4.1.1 & 5.2 79 until scanner.eos? 80 start = scanner.pos 81 len = nil 82 83 scanner.skip(RE_WSP) 84 85 name, value = scan_name_value(scanner, true) 86 value = nil if name.empty? 87 88 attrs = {} 89 90 until scanner.eos? 91 if scanner.skip(/,/) 92 # The comma is used as separator for concatenating multiple 93 # values of a header. 94 len = (scanner.pos - 1) - start 95 break 96 elsif scanner.skip(/;/) 97 scanner.skip(RE_WSP) 98 99 aname, avalue = scan_name_value(scanner, true) 100 101 next if aname.empty? || value.nil? 102 103 aname.downcase! 104 105 case aname 106 when "expires" 107 # RFC 6265 5.2.1 108 (avalue &&= Time.parse(avalue)) || next 109 when "max-age" 110 # RFC 6265 5.2.2 111 next unless /\A-?\d+\z/.match?(avalue) 112 113 avalue = Integer(avalue) 114 when "domain" 115 # RFC 6265 5.2.3 116 # An empty value SHOULD be ignored. 117 next if avalue.nil? || avalue.empty? 118 when "path" 119 # RFC 6265 5.2.4 120 # A relative path must be ignored rather than normalizing it 121 # to "/". 122 next unless avalue.start_with?("/") 123 when "secure", "httponly" 124 # RFC 6265 5.2.5, 5.2.6 125 avalue = true 126 end 127 attrs[aname] = avalue 128 end 129 end 130 131 len ||= scanner.pos - start 132 133 next if len > Cookie::MAX_LENGTH 134 135 yield(name, value, attrs) if name && !name.empty? && value 136 end 137 end
scan_dquoted(scanner)
[show source]
# File lib/httpx/plugins/cookies/set_cookie_parser.rb 23 def scan_dquoted(scanner) 24 s = +"" 25 26 until scanner.eos? 27 break if scanner.skip(/"/) 28 29 if scanner.skip(/\\/) 30 s << scanner.getch 31 elsif scanner.scan(/[^"\\]+/) 32 s << scanner.matched 33 end 34 end 35 36 s 37 end
scan_name_value(scanner, comma_as_separator = false)
[show source]
# File lib/httpx/plugins/cookies/set_cookie_parser.rb 62 def scan_name_value(scanner, comma_as_separator = false) 63 name = scanner.scan(RE_NAME) 64 name.rstrip! if name 65 66 if scanner.skip(/=/) 67 value = scan_value(scanner, comma_as_separator) 68 else 69 scan_value(scanner, comma_as_separator) 70 value = nil 71 end 72 [name, value] 73 end
scan_value(scanner, comma_as_separator = false)
[show source]
# File lib/httpx/plugins/cookies/set_cookie_parser.rb 39 def scan_value(scanner, comma_as_separator = false) 40 value = +"" 41 42 until scanner.eos? 43 if scanner.scan(/[^,;"]+/) 44 value << scanner.matched 45 elsif scanner.skip(/"/) 46 # RFC 6265 2.2 47 # A cookie-value may be DQUOTE'd. 48 value << scan_dquoted(scanner) 49 elsif scanner.check(/;/) 50 break 51 elsif comma_as_separator && scanner.check(RE_COOKIE_COMMA) 52 break 53 else 54 value << scanner.getch 55 end 56 end 57 58 value.rstrip! 59 value 60 end