Permalink
Browse files

Added first class response object that includes original body and sta…

…tus code.

  response = HTTParty.get('http://google.com')
  puts response.original_body, response.status

Now parsing all response types and no longer raising exceptions. This is
because some non-200 responses return important information.
  • Loading branch information...
1 parent a2686cf commit 8b528632c1e8a7c21b4daedbfd09b4fff6e365a4 @jnunemaker committed Jan 28, 2009
Showing with 75 additions and 22 deletions.
  1. +3 −1 History
  2. +3 −2 lib/httparty.rb
  3. +15 −18 lib/httparty/request.rb
  4. +27 −0 lib/httparty/response.rb
  5. +27 −1 spec/httparty/request_spec.rb
View
@@ -1,8 +1,10 @@
== 0.2.7 2009-01-28
-* 2 minor fixes, 1 minor enhancement
+* 2 minor fixes, 1 minor enhancement, 2 major enhancements
* fixed undefined method add_node for nil class error that occasionally happened (juliocesar)
* Handle nil or unexpected values better when typecasting. (Brian Landau)
* More robust handling of mime types (Alex Vollmer)
+ * Added first class response object that includes original body and status code (Alex Vollmer)
+ * Now parsing all response types as some non-200 responses provide important information, this means no more exception raising (Alex Vollmer)
== 0.2.6 2009-01-05
* 1 minor bug fix
View
@@ -19,7 +19,7 @@ module HTTParty
'application/javascript' => :json,
'text/javascript' => :json,
'text/html' => :html
- }
+ } unless defined?(AllowedFormats)
def self.included(base)
base.extend ClassMethods
@@ -118,4 +118,5 @@ def self.delete(*args)
end
require 'httparty/exceptions'
-require 'httparty/request'
+require 'httparty/request'
+require 'httparty/response'
@@ -87,29 +87,26 @@ def query_string(uri) #:nodoc:
# Raises exception Net::XXX (http error code) if an http error occured
def handle_response!(response) #:nodoc:
case response
- when Net::HTTPSuccess
- parse_response(response.body)
- when Net::HTTPRedirection
- options[:limit] -= 1
- self.path = response['location']
- perform
- else
- response.instance_eval { class << self; attr_accessor :body_parsed; end }
- begin; response.body_parsed = parse_response(response.body); rescue; end
- response.error! # raises exception corresponding to http error Net::XXX
- end
+ when Net::HTTPRedirection
+ options[:limit] -= 1
+ self.path = response['location']
+ perform
+ else
+ parsed_response = parse_response(response.body)
+ Response.new(parsed_response, response.body, response.code)
+ end
end
def parse_response(body) #:nodoc:
return nil if body.nil? or body.empty?
case format
- when :xml
- ToHashParser.from_xml(body)
- when :json
- JSON.parse(body)
- else
- body
- end
+ when :xml
+ ToHashParser.from_xml(body)
+ when :json
+ JSON.parse(body)
+ else
+ body
+ end
end
# Uses the HTTP Content-Type header to determine the format of the response
@@ -0,0 +1,27 @@
+module HTTParty
+ class Response
+ attr_accessor :body, :code
+
+ def initialize(delegate, body, code)
+ @delegate = delegate
+ @body = body
+ @code = code
+ end
+
+ def method_missing(name, *args)
+ @delegate.send(name, *args)
+ end
+
+ def ==(other)
+ @delegate == other
+ end
+
+ def nil?
+ @delegate.nil?
+ end
+
+ def pretty_print(q)
+ @delegate.pretty_print(q)
+ end
+ end
+end
@@ -79,6 +79,32 @@
@request.options[:format] = :json
@request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
end
+
+ describe 'with non-200 responses' do
+
+ it 'should return a valid object for 4xx response' do
+ http_response = Net::HTTPUnauthorized.new('1.1', 401, '')
+ http_response.stub!(:body).and_return('<foo><bar>yes</bar></foo>')
+
+ @request.should_receive(:get_response).and_return(http_response)
+ resp = @request.perform
+ resp.code.should == 401
+ resp.body.should == "<foo><bar>yes</bar></foo>"
+ resp['foo']['bar'].should == "yes"
+ end
+
+ it 'should return a valid object for 5xx response' do
+ http_response = Net::HTTPUnauthorized.new('1.1', 500, '')
+ http_response.stub!(:body).and_return('<foo><bar>error</bar></foo>')
+
+ @request.should_receive(:get_response).and_return(http_response)
+ resp = @request.perform
+ resp.code.should == 500
+ resp.body.should == "<foo><bar>error</bar></foo>"
+ resp['foo']['bar'].should == "error"
+ end
+
+ end
end
it "should not attempt to parse empty responses" do
@@ -87,7 +113,7 @@
response = Net::HTTPNoContent.new("1.1", 204, "No content for you")
response.stub!(:body).and_return(nil)
http.stub!(:request).and_return(response)
-
+
@request.options[:format] = :xml
@request.perform.should be_nil

0 comments on commit 8b52863

Please sign in to comment.