diff --git a/lib/restclient/abstract_response.rb b/lib/restclient/abstract_response.rb index f0dc1cb..cde1bd6 100644 --- a/lib/restclient/abstract_response.rb +++ b/lib/restclient/abstract_response.rb @@ -39,11 +39,20 @@ module RestClient history end - # Hash of cookies extracted from response headers + # Hash of cookies extracted from response headers. + # + # NB: This will return only cookies whose domain matches this request, and + # may not even return all of those cookies if there are duplicate names. + # Use the full cookie_jar for more nuanced access. + # + # @see #cookie_jar + # + # @return [Hash] + # def cookies hash = {} - cookie_jar.cookies.each do |cookie| + cookie_jar.cookies(@request.uri).each do |cookie| hash[cookie.name] = cookie.value end @@ -57,7 +66,7 @@ module RestClient def cookie_jar return @cookie_jar if @cookie_jar - jar = HTTP::CookieJar.new + jar = @request.cookie_jar.dup headers.fetch(:set_cookie, []).each do |cookie| jar.parse(cookie, @request.uri) end @@ -185,10 +194,8 @@ module RestClient new_args[:headers] = request.headers new_args[:max_redirects] = request.max_redirects - 1 - # TODO: figure out what to do with original :cookie, :cookies values - new_args[:headers]['Cookie'] = HTTP::Cookie.cookie_value( - cookie_jar.cookies(new_args.fetch(:url))) - + # pass through our new cookie jar + new_args[:cookies] = cookie_jar # prepare new request new_req = Request.new(new_args) diff --git a/spec/helpers.rb b/spec/helpers.rb index 45956a2..1de717d 100644 --- a/spec/helpers.rb +++ b/spec/helpers.rb @@ -16,7 +16,7 @@ module Helpers def request_double(url: 'http://example.com', method: 'get') double('request', url: url, uri: URI.parse(url), method: method, - user: nil, password: nil, + user: nil, password: nil, cookie_jar: HTTP::CookieJar.new, redirection_history: nil, args: {url: url, method: method}) end end diff --git a/spec/unit/abstract_response_spec.rb b/spec/unit/abstract_response_spec.rb index 6824aa2..55c4a14 100644 --- a/spec/unit/abstract_response_spec.rb +++ b/spec/unit/abstract_response_spec.rb @@ -92,7 +92,8 @@ describe RestClient::AbstractResponse, :include_helpers do it 'handles cookies when URI scheme is implicit' do net_http_res = double('net http response') net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/']) - request = double(url: 'example.com', uri: URI.parse('http://example.com'), method: 'get') + request = double(url: 'example.com', uri: URI.parse('http://example.com'), + method: 'get', cookie_jar: HTTP::CookieJar.new) response = MyAbstractResponse.new(net_http_res, request) response.cookie_jar.should be_a HTTP::CookieJar diff --git a/spec/unit/response_spec.rb b/spec/unit/response_spec.rb index 60f6c7e..2108020 100644 --- a/spec/unit/response_spec.rb +++ b/spec/unit/response_spec.rb @@ -120,10 +120,13 @@ describe RestClient::Response, :include_helpers do RestClient::Request.execute(:url => 'http://some/resource', :method => :get).body.should eq 'Qux' end - it 'does not keep cookies across domains' do - stub_request(:get, 'http://some/resource').to_return(:body => '', :status => 301, :headers => {'Set-Cookie' => 'Foo=Bar', 'Location' => 'http://new/resource', }) - stub_request(:get, 'http://new/resource').with(:headers => {'Cookie' => ''}).to_return(:body => 'Qux') - RestClient::Request.execute(:url => 'http://some/resource', :method => :get).body.should eq 'Qux' + it 'respects cookie domains on redirect' do + stub_request(:get, 'http://some.example.com/').to_return(:body => '', :status => 301, + :headers => {'Set-Cookie' => 'Foo=Bar', 'Location' => 'http://new.example.com/', }) + stub_request(:get, 'http://new.example.com/').with( + :headers => {'Cookie' => 'passedthrough=1'}).to_return(:body => 'Qux') + + RestClient::Request.execute(:url => 'http://some.example.com/', :method => :get, cookies: [HTTP::Cookie.new('passedthrough', '1', domain: 'new.example.com', path: '/')]).body.should eq 'Qux' end it "doesn't follow a 301 when the request is a post" do