Permalink
Browse files

Refactor redirection handling

Closes gh-56
  • Loading branch information...
1 parent e9f8739 commit 7ea359d0eb7941def6ef122c025dc455041c76bd @sandro sandro committed Jan 18, 2011
Showing with 59 additions and 25 deletions.
  1. +13 −0 lib/httparty.rb
  2. +21 −22 lib/httparty/request.rb
  3. +12 −2 spec/httparty/request_spec.rb
  4. +12 −0 spec/httparty_spec.rb
  5. +1 −1 spec/support/stub_response.rb
View
@@ -184,6 +184,19 @@ def cookies(h={})
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
@@ -170,34 +170,21 @@ def query_string(uri)
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 @@ def handle_deflation
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 @@
@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
@@ -372,6 +372,18 @@ class MyParser < HTTParty::Parser
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 @@ def stub_http_response_with(filename)
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)

0 comments on commit 7ea359d

Please sign in to comment.