diff options
author | Santiago Pastorino <santiago@wyeworks.com> | 2015-05-20 07:41:48 -0300 |
---|---|---|
committer | Santiago Pastorino <santiago@wyeworks.com> | 2015-05-20 07:41:48 -0300 |
commit | b102793a419135d792b29def4b0c368272723904 (patch) | |
tree | 88e23871a8cf0a6ee7009f0025ba062507ecc3ff | |
parent | 9099a0ee6a32d4f0a0058bbb1891c0b2853fcdcd (diff) | |
parent | e8dba2a73bb6681d863779365e9e3c14118cfa20 (diff) | |
download | rack-b102793a419135d792b29def4b0c368272723904.tar.gz |
Merge pull request #857 from jodosha/utils-parse-cookies
Extracted Rack::Utils.parse_cookies
-rw-r--r-- | lib/rack.rb | 1 | ||||
-rw-r--r-- | lib/rack/request.rb | 12 | ||||
-rw-r--r-- | lib/rack/utils.rb | 13 | ||||
-rw-r--r-- | test/spec_utils.rb | 17 |
4 files changed, 33 insertions, 10 deletions
diff --git a/lib/rack.rb b/lib/rack.rb index 56717be9..0dcb6ed3 100644 --- a/lib/rack.rb +++ b/lib/rack.rb @@ -38,6 +38,7 @@ module Rack CACHE_CONTROL = 'Cache-Control'.freeze CONTENT_LENGTH = 'Content-Length'.freeze CONTENT_TYPE = 'Content-Type'.freeze + HTTP_COOKIE = 'HTTP_COOKIE'.freeze GET = 'GET'.freeze POST = 'POST'.freeze diff --git a/lib/rack/request.rb b/lib/rack/request.rb index e2cdaf47..7167f338 100644 --- a/lib/rack/request.rb +++ b/lib/rack/request.rb @@ -300,18 +300,10 @@ module Rack def cookies hash = @env["rack.request.cookie_hash"] ||= {} - string = @env["HTTP_COOKIE"] + string = @env[HTTP_COOKIE] return hash if string == @env["rack.request.cookie_string"] - hash.clear - - # According to RFC 2109: - # If multiple cookies satisfy the criteria above, they are ordered in - # the Cookie header such that those with more specific Path attributes - # precede those with less specific. Ordering with respect to other - # attributes (e.g., Domain) is unspecified. - cookies = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s } - cookies.each { |k,v| hash[k] = Array === v ? v.first : v } + hash.replace Utils.parse_cookies(@env) @env["rack.request.cookie_string"] = string hash end diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 759fa4d3..590b41bd 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -273,6 +273,19 @@ module Rack end module_function :select_best_encoding + def parse_cookies(env) + # According to RFC 2109: + # If multiple cookies satisfy the criteria above, they are ordered in + # the Cookie header such that those with more specific Path attributes + # precede those with less specific. Ordering with respect to other + # attributes (e.g., Domain) is unspecified. + Hash[].tap do |hash| + cookies = parse_query(env[HTTP_COOKIE], ';,') { |s| unescape(s) rescue s } + cookies.each { |k,v| hash[k] = Array === v ? v.first : v } + end + end + module_function :parse_cookies + def set_cookie_header!(header, key, value) case value when Hash diff --git a/test/spec_utils.rb b/test/spec_utils.rb index dbf958c4..0a295902 100644 --- a/test/spec_utils.rb +++ b/test/spec_utils.rb @@ -313,6 +313,23 @@ describe Rack::Utils do Rack::Utils.build_query(key => nil).should.equal Rack::Utils.escape(key) end + should "parse cookies" do + env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "zoo=m") + Rack::Utils.parse_cookies(env).should.equal({"zoo" => "m"}) + + env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%") + Rack::Utils.parse_cookies(env).should.equal({"foo" => "%"}) + + env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;foo=car") + Rack::Utils.parse_cookies(env).should.equal({"foo" => "bar"}) + + env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m") + Rack::Utils.parse_cookies(env).should.equal({"foo" => "bar", "quux" => "h&m"}) + + env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar").freeze + Rack::Utils.parse_cookies(env).should.equal({"foo" => "bar"}) + end + should "parse q-values" do # XXX handle accept-extension Rack::Utils.q_values("foo;q=0.5,bar,baz;q=0.9").should.equal [ |