mirror of
https://github.com/rest-client/rest-client.git
synced 2022-11-09 13:49:40 -05:00
Cookies set in a response should be kept in a redirect. Closes #38
This commit is contained in:
parent
ec80597fae
commit
75ab0dc7ef
5 changed files with 38 additions and 18 deletions
12
README.rdoc
12
README.rdoc
|
@ -100,11 +100,11 @@ A block can be passed to the RestClient method, this block will then be called w
|
|||
Response.return! can be called to invoke the default response's behavior.
|
||||
|
||||
# Don't raise exceptions but return the response
|
||||
RestClient.get('http://example.com/resource'){|response, request| response }
|
||||
RestClient.get('http://example.com/resource'){|response, request, result| response }
|
||||
➔ 404 Resource Not Found | text/html 282 bytes
|
||||
|
||||
# Manage a specific error code
|
||||
RestClient.get('http://my-rest-service.com/resource'){ |response, request, &block|
|
||||
RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
|
||||
case response.code
|
||||
when 200
|
||||
p "It worked !"
|
||||
|
@ -112,7 +112,7 @@ Response.return! can be called to invoke the default response's behavior.
|
|||
when 423
|
||||
raise SomeCustomExceptionIfYouWant
|
||||
else
|
||||
response.return!(request, &block)
|
||||
response.return!(request, result, &block)
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -120,11 +120,11 @@ Response.return! can be called to invoke the default response's behavior.
|
|||
# RFC : "If the 301, 302 or 307 status code is received in response to a request other than GET or HEAD,
|
||||
# the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user,
|
||||
# since this might change the conditions under which the request was issued."
|
||||
RestClient.get('http://my-rest-service.com/resource'){ |response, request, &block|
|
||||
RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
|
||||
if [301, 302, 307].include? response.code
|
||||
response.follow_redirection(request, &block)
|
||||
response.follow_redirection(request, result, &block)
|
||||
else
|
||||
response.return!(request, &block)
|
||||
response.return!(request, result, &block)
|
||||
end
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
- add support for RestClient.options
|
||||
- fix tests for 1.9.2 (patch provided by Niko Dittmann)
|
||||
- block passing in Resource#[] (patch provided by Niko Dittmann)
|
||||
- cookies set in a response should be kept in a redirect
|
||||
|
||||
# 1.6.0
|
||||
|
||||
|
|
|
@ -25,30 +25,25 @@ module RestClient
|
|||
# Hash of cookies extracted from response headers
|
||||
def cookies
|
||||
@cookies ||= (self.headers[:set_cookie] || {}).inject({}) do |out, cookie_content|
|
||||
CGI::Cookie::parse(cookie_content).each do |key, cookie|
|
||||
unless ['expires', 'path'].include? key
|
||||
out[CGI::escape(key)] = cookie.value[0] ? (CGI::escape(cookie.value[0]) || '') : ''
|
||||
end
|
||||
end
|
||||
out
|
||||
out.merge parse_cookie(cookie_content)
|
||||
end
|
||||
end
|
||||
|
||||
# Return the default behavior corresponding to the response code:
|
||||
# the response itself for code in 200..206, redirection for 301, 302 and 307 in get and head cases, redirection for 303 and an exception in other cases
|
||||
def return! request = nil, &block
|
||||
def return! request = nil, result = nil, & block
|
||||
if (200..207).include? code
|
||||
self
|
||||
elsif [301, 302, 307].include? code
|
||||
unless [:get, :head].include? args[:method]
|
||||
raise Exceptions::EXCEPTIONS_MAP[code].new(self, code)
|
||||
else
|
||||
follow_redirection(request, &block)
|
||||
follow_redirection(request, result, & block)
|
||||
end
|
||||
elsif code == 303
|
||||
args[:method] = :get
|
||||
args.delete :payload
|
||||
follow_redirection(request, &block)
|
||||
follow_redirection(request, result, & block)
|
||||
elsif Exceptions::EXCEPTIONS_MAP[code]
|
||||
raise Exceptions::EXCEPTIONS_MAP[code].new(self, code)
|
||||
else
|
||||
|
@ -65,7 +60,7 @@ module RestClient
|
|||
end
|
||||
|
||||
# Follow a redirection
|
||||
def follow_redirection request = nil, &block
|
||||
def follow_redirection request = nil, result = nil, & block
|
||||
url = headers[:location]
|
||||
if url !~ /^http/
|
||||
url = URI.parse(args[:url]).merge(url).to_s
|
||||
|
@ -75,6 +70,10 @@ module RestClient
|
|||
args[:password] = request.password
|
||||
args[:user] = request.user
|
||||
args[:headers] = request.headers
|
||||
# pass any cookie set in the result
|
||||
if result && result['set-cookie']
|
||||
args[:headers][:cookies] = (args[:headers][:cookies] || {}).merge(parse_cookie(result['set-cookie']))
|
||||
end
|
||||
end
|
||||
Request.execute args, &block
|
||||
end
|
||||
|
@ -85,5 +84,19 @@ module RestClient
|
|||
out
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Parse a cookie value and return its content in an Hash
|
||||
def parse_cookie cookie_content
|
||||
out = {}
|
||||
CGI::Cookie::parse(cookie_content).each do |key, cookie|
|
||||
unless ['expires', 'path'].include? key
|
||||
out[CGI::escape(key)] = cookie.value[0] ? (CGI::escape(cookie.value[0]) || '') : ''
|
||||
end
|
||||
end
|
||||
out
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -215,9 +215,9 @@ module RestClient
|
|||
end
|
||||
|
||||
if block_given?
|
||||
block.call(response, self, & block)
|
||||
block.call(response, self, res, & block)
|
||||
else
|
||||
response.return!(self, & block)
|
||||
response.return!(self, res, & block)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -90,6 +90,12 @@ describe RestClient::Response do
|
|||
RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :user => 'foo', :password => 'bar', :headers => {:accept => :json}).body.should == 'Foo'
|
||||
end
|
||||
|
||||
it "follows a redirection and keep the cookies" do
|
||||
stub_request(:get, 'http://some/resource').to_return(:body => '', :status => 301, :headers => {'Set-Cookie' => CGI::Cookie.new('Foo', 'Bar'), 'Location' => 'http://new/resource', })
|
||||
stub_request(:get, 'http://new/resource').with(:headers => {'Cookie' => 'Foo=Bar'}).to_return(:body => 'Qux')
|
||||
RestClient::Request.execute(:url => 'http://some/resource', :method => :get).body.should == 'Qux'
|
||||
end
|
||||
|
||||
it "doesn't follow a 301 when the request is a post" do
|
||||
net_http_res = mock('net http response', :code => 301)
|
||||
response = RestClient::Response.create('abc', net_http_res, {:method => :post})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue