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:
parent
e9f8739b63
commit
7ea359d0eb
5 changed files with 59 additions and 25 deletions
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue