aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-09-12 10:11:39 -0700
committerJon Leighton <j@jonathanleighton.com>2011-09-12 10:11:39 -0700
commit8397a564cb03dec8bd3d083f3376ecdd439dbb70 (patch)
tree7d7299d979bf2197c7b3ecf343474bbb70857461 /activeresource
parent11fa70dd0903a75f2a507dd609ea640e8ec99373 (diff)
parenta06d17480ff533fbc375df219a4e70886fb4899b (diff)
downloadrails-8397a564cb03dec8bd3d083f3376ecdd439dbb70.tar.gz
rails-8397a564cb03dec8bd3d083f3376ecdd439dbb70.tar.bz2
rails-8397a564cb03dec8bd3d083f3376ecdd439dbb70.zip
Merge pull request #2678 from jmileham/ares_content_length_bug
ActiveResource shouldn't rely on the presence of Content-Length
Diffstat (limited to 'activeresource')
-rw-r--r--activeresource/lib/active_resource/base.rb10
-rw-r--r--activeresource/test/cases/base_test.rb30
2 files changed, 36 insertions, 4 deletions
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 990d9a38dd..1ffd83b91d 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -1357,7 +1357,9 @@ module ActiveResource
end
def load_attributes_from_response(response)
- if !response['Content-Length'].blank? && response['Content-Length'] != "0" && !response.body.nil? && response.body.strip.size > 0
+ if (response_code_allows_body?(response.code) &&
+ (response['Content-Length'].nil? || response['Content-Length'] != "0") &&
+ !response.body.nil? && response.body.strip.size > 0)
load(self.class.format.decode(response.body), true)
@persisted = true
end
@@ -1381,6 +1383,12 @@ module ActiveResource
end
private
+
+ # Determine whether the response is allowed to have a body per HTTP 1.1 spec section 4.4.1
+ def response_code_allows_body?(c)
+ !((100..199).include?(c) || [204,304].include?(c))
+ end
+
# Tries to find a resource for a given collection name; if it fails, then the resource is created
def find_or_create_resource_for_collection(name)
find_or_create_resource_for(ActiveSupport::Inflector.singularize(name.to_s))
diff --git a/activeresource/test/cases/base_test.rb b/activeresource/test/cases/base_test.rb
index f45652d988..d4063fa299 100644
--- a/activeresource/test/cases/base_test.rb
+++ b/activeresource/test/cases/base_test.rb
@@ -636,13 +636,37 @@ class BaseTest < Test::Unit::TestCase
assert_nil p.__send__(:id_from_response, resp)
end
- def test_load_attributes_from_response
- p = Person.new
+ def test_not_persisted_with_no_body_and_positive_content_length
resp = ActiveResource::Response.new(nil)
resp['Content-Length'] = "100"
- assert_nil p.__send__(:load_attributes_from_response, resp)
+ Person.connection.expects(:post).returns(resp)
+ assert !Person.create.persisted?
+ end
+
+ def test_not_persisted_with_body_and_zero_content_length
+ resp = ActiveResource::Response.new(@rick)
+ resp['Content-Length'] = "0"
+ Person.connection.expects(:post).returns(resp)
+ assert !Person.create.persisted?
end
+ # These response codes aren't allowed to have bodies per HTTP spec
+ def test_not_persisted_with_empty_response_codes
+ [100,101,204,304].each do |status_code|
+ resp = ActiveResource::Response.new(@rick, status_code)
+ Person.connection.expects(:post).returns(resp)
+ assert !Person.create.persisted?
+ end
+ end
+
+ # Content-Length is not required by HTTP 1.1, so we should read
+ # the body anyway in its absence.
+ def test_persisted_with_no_content_length
+ resp = ActiveResource::Response.new(@rick)
+ resp['Content-Length'] = nil
+ Person.connection.expects(:post).returns(resp)
+ assert Person.create.persisted?
+ end
def test_create_with_custom_prefix
matzs_house = StreetAddress.new(:person_id => 1)