diff --git a/lib/rack/test/cookie_jar.rb b/lib/rack/test/cookie_jar.rb index 2730ddc..b3f53d2 100644 --- a/lib/rack/test/cookie_jar.rb +++ b/lib/rack/test/cookie_jar.rb @@ -94,13 +94,12 @@ def valid?(uri) real_domain = domain =~ /^\./ ? domain[1..-1] : domain !!((!secure? || (secure? && uri.scheme == 'https')) && - uri.host =~ Regexp.new("#{'^' if @exact_domain_match}#{Regexp.escape(real_domain)}$", Regexp::IGNORECASE) && - uri.path =~ Regexp.new("^#{Regexp.escape(path)}")) + uri.host =~ Regexp.new("#{'^' if @exact_domain_match}#{Regexp.escape(real_domain)}$", Regexp::IGNORECASE)) end # Cookies that do not match the URI will not be sent in requests to the URI. def matches?(uri) - !expired? && valid?(uri) + !expired? && valid?(uri) && valid_path?(uri.path) end # Order cookies by name, path, and domain. @@ -120,6 +119,11 @@ def to_h private + # Whether the path of URI matches the Cookie path + def valid_path?(uri_path) + !!(uri_path =~ Regexp.new("^#{Regexp.escape(path)}")) + end + # The default URI to use for the cookie, including just the host. def default_uri URI.parse('//' + @default_host + '/') diff --git a/spec/fixtures/fake_app.rb b/spec/fixtures/fake_app.rb index d8b986a..3cfeff2 100644 --- a/spec/fixtures/fake_app.rb +++ b/spec/fixtures/fake_app.rb @@ -60,6 +60,10 @@ def handle(env) end end + if path == '/redirect-with-cookie' && method == 'GET' + return [302, { 'set-cookie' => "value=1; path=/cookies;", 'location' => '/cookies/show' }, []] + end + if path == '/redirected' additional_info = if method == 'GET' ", session #{session.inspect} with options #{env['rack.session.options'].inspect}" diff --git a/spec/rack/test/cookie_object_spec.rb b/spec/rack/test/cookie_object_spec.rb index 98f5a54..25852cf 100644 --- a/spec/rack/test/cookie_object_spec.rb +++ b/spec/rack/test/cookie_object_spec.rb @@ -6,8 +6,8 @@ describe Rack::Test::Cookie do value = 'the cookie value'.freeze domain = 'www.example.org'.freeze - path = '/'.freeze - expires = 'Mon, 10 Aug 2015 14:40:57 0100'.freeze + path = '/foo'.freeze + expires = (Time.now + (24 * 60 * 60)).httpdate cookie_string = [ 'cookie_name=' + CGI.escape(value), 'domain=' + domain, @@ -45,6 +45,16 @@ cookie('; secure').valid?(URI.parse('/')).must_equal false end + it '#valid? is indifferent to matching paths' do + cookie.valid?(URI.parse('https://www.example.org/foo')).must_equal true + cookie.valid?(URI.parse('https://www.example.org/bar')).must_equal true + end + + it '#matches? demands matching paths' do + cookie.matches?(URI.parse('https://www.example.org/foo')).must_equal true + cookie.matches?(URI.parse('https://www.example.org/bar')).must_equal false + end + it '#http_only? for a non HTTP only cookie returns false' do cookie.http_only?.must_equal false end diff --git a/spec/rack/test/cookie_spec.rb b/spec/rack/test/cookie_spec.rb index 1595004..f88c431 100644 --- a/spec/rack/test/cookie_spec.rb +++ b/spec/rack/test/cookie_spec.rb @@ -258,4 +258,10 @@ def cookie.expired?; true end request '/cookies/show', cookie: 'value=1' last_request.cookies.must_equal 'value' => '1' end + + it 'sets and subsequently sends cookies when redirecting to the path of the cookie' do + get '/redirect-with-cookie' + follow_redirect! + last_request.cookies.must_equal 'value' => '1' + end end