Class: ApiHammer::Body
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#content_type ⇒ Object
readonly
Returns the value of attribute content_type.
Instance Method Summary collapse
- #content_type_attrs ⇒ Object
- #filtered(options) ⇒ Object
-
#initialize(body, content_type) ⇒ Body
constructor
A new instance of Body.
-
#jsonifiable ⇒ Object
deal with the vagaries of getting the response body in a form which JSON gem will not cry about generating.
- #media_type ⇒ Object
-
#object ⇒ Object
parses the body to an object.
Constructor Details
#initialize(body, content_type) ⇒ Body
Returns a new instance of Body.
7 8 9 10 |
# File 'lib/api_hammer/body.rb', line 7 def initialize(body, content_type) @body = body @content_type = content_type end |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
5 6 7 |
# File 'lib/api_hammer/body.rb', line 5 def body @body end |
#content_type ⇒ Object (readonly)
Returns the value of attribute content_type.
5 6 7 |
# File 'lib/api_hammer/body.rb', line 5 def content_type @content_type end |
Instance Method Details
#content_type_attrs ⇒ Object
39 40 41 |
# File 'lib/api_hammer/body.rb', line 39 def content_type_attrs @content_type_attrs ||= ContentTypeAttrs.new(content_type) end |
#filtered(options) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/api_hammer/body.rb', line 23 def filtered() @filtered ||= Body.new(begin if media_type == 'application/json' begin ApiHammer::Filtration::Json.new(body, ).filter rescue JSON::ParserError body end elsif media_type == 'application/x-www-form-urlencoded' ApiHammer::Filtration::FormEncoded.new(body, ).filter else body end end, content_type) end |
#jsonifiable ⇒ Object
deal with the vagaries of getting the response body in a form which JSON gem will not cry about generating
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/api_hammer/body.rb', line 49 def jsonifiable @jsonifiable ||= Body.new(catch(:jsonifiable) do original_body = self.body unless original_body.is_a?(String) begin # if the response body is not a string, but JSON doesn't complain # about dumping whatever it is, go ahead and use it JSON.generate([original_body]) throw :jsonifiable, original_body rescue # otherwise return nil - don't know what to do with whatever this object is throw :jsonifiable, nil end end # first try to change the string's encoding per the Content-Type header body = original_body.dup unless body.valid_encoding? # I think this always comes in as ASCII-8BIT anyway so may never get here. hopefully. body.force_encoding('ASCII-8BIT') end content_type_attrs = ContentTypeAttrs.new(content_type) if content_type_attrs.parsed? charset = content_type_attrs['charset'].first if charset && Encoding.list.any? { |enc| enc.to_s.downcase == charset.downcase } if body.dup.force_encoding(charset).valid_encoding? body.force_encoding(charset) else # I guess just ignore the specified encoding if the result is not valid. fall back to # something else below. end end end begin JSON.generate([body]) rescue Encoding::UndefinedConversionError, JSON::GeneratorError # if updating by content-type didn't do it, try UTF8 since JSON wants that - but only # if it seems to be valid utf8. # don't try utf8 if the response content-type indicated something else. try_utf8 = !(content_type_attrs && content_type_attrs.parsed? && content_type_attrs['charset'].any? { |cs| !['utf8', ''].include?(cs.downcase) }) if try_utf8 && body.dup.force_encoding('UTF-8').valid_encoding? body.force_encoding('UTF-8') else # I'm not sure if there is a way in this situation to get JSON gem to generate the # string correctly. fall back to an array of codepoints I guess? this is a weird # solution but the best I've got for now. body = body.codepoints.to_a end end body end, content_type) end |
#media_type ⇒ Object
43 44 45 |
# File 'lib/api_hammer/body.rb', line 43 def media_type content_type_attrs.media_type end |
#object ⇒ Object
parses the body to an object
13 14 15 16 17 18 19 20 21 |
# File 'lib/api_hammer/body.rb', line 13 def object instance_variable_defined?(:@object) ? @object : @object = begin if media_type == 'application/json' JSON.parse(body) rescue nil elsif media_type == 'application/x-www-form-urlencoded' CGI.parse(body).map { |k, vs| {k => vs.last} }.inject({}, &:update) end end end |