1
0
Fork 0
mirror of https://github.com/jnunemaker/httparty synced 2023-03-27 23:23:07 -04:00

Refactor redirection handling

Closes gh-56
This commit is contained in:
Sandro Turriate 2011-01-18 15:36:56 -05:00
parent e9f8739b63
commit 7ea359d0eb
5 changed files with 59 additions and 25 deletions

View file

@ -184,6 +184,19 @@ module HTTParty
default_cookies.add_cookies(h)
end
# Proceed to the location header when an HTTP response dictates a redirect.
# Redirects are always followed by default.
#
# @example
# class Foo
# include HTTParty
# base_uri 'http://google.com'
# follow_redirects true
# end
def follow_redirects(value = true)
default_options[:follow_redirects] = value
end
# Allows setting the format with which to parse.
# Must be one of the allowed formats ie: json, xml
#

View file

@ -170,34 +170,21 @@ module HTTParty
query_string_parts << options[:query] unless options[:query].nil?
end
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
end
# Raises exception Net::XXX (http error code) if an http error occured
def handle_response
case last_response
when Net::HTTPMultipleChoice, # 300
Net::HTTPMovedPermanently, # 301
Net::HTTPFound, # 302
Net::HTTPSeeOther, # 303
Net::HTTPUseProxy, # 305
Net::HTTPTemporaryRedirect
if options[:follow_redirects] && last_response.key?('location')
options[:limit] -= 1
new_uri = last_response['location']
if new_uri =~ /^http/
self.path = new_uri
else
self.path.merge(new_uri)
end
self.redirect = true
self.http_method = Net::HTTP::Get unless options[:maintain_method_across_redirects]
capture_cookies(last_response)
return perform
end
if response_redirects?
options[:limit] -= 1
self.path = last_response['location']
self.redirect = true
self.http_method = Net::HTTP::Get unless options[:maintain_method_across_redirects]
capture_cookies(last_response)
perform
else
Response.new(self, last_response, parse_response(last_response.body))
end
Response.new(self, last_response, parse_response(last_response.body))
end
# Inspired by Ruby 1.9
@ -211,6 +198,18 @@ module HTTParty
end
end
def response_redirects?
case last_response
when Net::HTTPMultipleChoice, # 300
Net::HTTPMovedPermanently, # 301
Net::HTTPFound, # 302
Net::HTTPSeeOther, # 303
Net::HTTPUseProxy, # 305
Net::HTTPTemporaryRedirect
options[:follow_redirects] && last_response.key?('location')
end
end
def parse_response(body)
parser.call(body, format)
end

View file

@ -322,9 +322,19 @@ describe HTTParty::Request do
@request.perform.should == {"hash" => {"foo" => "bar"}}
end
it "returns the Net::HTTP response if the 300 does not contain a location header" do
it "redirects if a 300 contains a relative location header" do
redirect = stub_response '', 300
redirect['location'] = '/foo/bar'
ok = stub_response('<hash><foo>bar</foo></hash>', 200)
@http.stub!(:request).and_return(redirect, ok)
response = @request.perform
response.request.uri.request_uri.should == "/foo/bar"
response.should == {"hash" => {"foo" => "bar"}}
end
it "returns the HTTParty::Response when the 300 does not contain a location header" do
net_response = stub_response '', 300
@request.perform.should be_kind_of(Net::HTTPMultipleChoice)
HTTParty::Response.should === @request.perform
end
end

View file

@ -372,6 +372,18 @@ describe HTTParty do
end
end
describe ".follow_redirects" do
it "sets follow redirects to true by default" do
@klass.follow_redirects
@klass.default_options[:follow_redirects].should be_true
end
it "sets the follow_redirects option to false" do
@klass.follow_redirects false
@klass.default_options[:follow_redirects].should be_false
end
end
describe ".query_string_normalizer" do
it "sets the query_string_normalizer option" do
normalizer = proc {}

View file

@ -14,10 +14,10 @@ module HTTParty
end
def stub_response(body, code = 200)
@request.options[:base_uri] ||= 'http://localhost'
unless defined?(@http) && @http
@http = Net::HTTP.new('localhost', 80)
@request.stub!(:http).and_return(@http)
@request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
end
response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body)