From cb0dd1fd3b50439ea16553d5b6ccecd699e7f253 Mon Sep 17 00:00:00 2001 From: Pedro Belo Date: Mon, 29 Jun 2009 16:22:54 -0700 Subject: [PATCH] decode response body for exceptions too (401, 404, etc) --- lib/restclient/exceptions.rb | 4 ++++ lib/restclient/request.rb | 4 ++-- spec/exceptions_spec.rb | 15 +++++++++++++-- spec/request_spec.rb | 8 ++++---- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/restclient/exceptions.rb b/lib/restclient/exceptions.rb index 5f4ae31..1d0ce91 100644 --- a/lib/restclient/exceptions.rb +++ b/lib/restclient/exceptions.rb @@ -18,6 +18,10 @@ module RestClient def http_code @response.code.to_i if @response end + + def http_body + RestClient::Request.decode(@response['content-encoding'], @response.body) if @response + end end # A redirect was encountered; caught by execute to retry with the new url. diff --git a/lib/restclient/request.rb b/lib/restclient/request.rb index f303144..71f1b05 100644 --- a/lib/restclient/request.rb +++ b/lib/restclient/request.rb @@ -173,7 +173,7 @@ module RestClient if res.code =~ /\A2\d{2}\z/ # We don't decode raw requests unless @raw_response - decode res['content-encoding'], res.body if res.body + self.class.decode res['content-encoding'], res.body if res.body end elsif %w(301 302 303).include? res.code url = res.header['Location'] @@ -196,7 +196,7 @@ module RestClient end end - def decode(content_encoding, body) + def self.decode(content_encoding, body) if content_encoding == 'gzip' and not body.empty? Zlib::GzipReader.new(StringIO.new(body)).read elsif content_encoding == 'deflate' diff --git a/spec/exceptions_spec.rb b/spec/exceptions_spec.rb index fe6449b..b23b647 100644 --- a/spec/exceptions_spec.rb +++ b/spec/exceptions_spec.rb @@ -12,6 +12,10 @@ describe RestClient::Exception do end describe RestClient::RequestFailed do + before do + @response = mock('HTTP Response', :code => '502') + end + it "stores the http response on the exception" do begin raise RestClient::RequestFailed, :response @@ -21,11 +25,18 @@ describe RestClient::RequestFailed do end it "http_code convenience method for fetching the code as an integer" do - RestClient::RequestFailed.new(mock('res', :code => '502')).http_code.should == 502 + RestClient::RequestFailed.new(@response).http_code.should == 502 + end + + it "http_body convenience method for fetching the body (decoding when necessary)" do + @response.stub!(:[]).with('content-encoding').and_return('gzip') + @response.stub!(:body).and_return('compressed body') + RestClient::Request.should_receive(:decode).with('gzip', 'compressed body').and_return('plain body') + RestClient::RequestFailed.new(@response).http_body.should == 'plain body' end it "shows the status code in the message" do - RestClient::RequestFailed.new(mock('res', :code => '502')).to_s.should match(/502/) + RestClient::RequestFailed.new(@response).to_s.should match(/502/) end end diff --git a/spec/request_spec.rb b/spec/request_spec.rb index 1a34668..47842e2 100644 --- a/spec/request_spec.rb +++ b/spec/request_spec.rb @@ -22,19 +22,19 @@ describe RestClient::Request do end it "decodes an uncompressed result body by passing it straight through" do - @request.decode(nil, 'xyz').should == 'xyz' + RestClient::Request.decode(nil, 'xyz').should == 'xyz' end it "decodes a gzip body" do - @request.decode('gzip', "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000").should == "i'm gziped\n" + RestClient::Request.decode('gzip', "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000").should == "i'm gziped\n" end it "ingores gzip for empty bodies" do - @request.decode('gzip', '').should be_empty + RestClient::Request.decode('gzip', '').should be_empty end it "decodes a deflated body" do - @request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should == "some deflated text" + RestClient::Request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should == "some deflated text" end it "processes a successful result" do