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 && 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.nil? || aname.empty?) || value.nil? 102 103 aname.downcase! 104 105 case aname 106 when "expires" 107 next unless avalue 108 109 # RFC 6265 5.2.1 110 (avalue = Time.parse(avalue)) || next 111 when "max-age" 112 next unless avalue 113 # RFC 6265 5.2.2 114 next unless /\A-?\d+\z/.match?(avalue) 115 116 avalue = Integer(avalue) 117 when "domain" 118 # RFC 6265 5.2.3 119 # An empty value SHOULD be ignored. 120 next if avalue.nil? || avalue.empty? 121 when "path" 122 # RFC 6265 5.2.4 123 # A relative path must be ignored rather than normalizing it 124 # to "/". 125 next unless avalue && avalue.start_with?("/") 126 when "secure", "httponly" 127 # RFC 6265 5.2.5, 5.2.6 128 avalue = true 129 end 130 attrs[aname] = avalue 131 end 132 end 133 134 len ||= scanner.pos - start 135 136 next if len > Cookie::MAX_LENGTH 137 138 yield(name, value, attrs) if name && !name.empty? && value 139 end 140 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