class ApiHammer::Body
Attributes
body[R]
content_type[R]
Public Class Methods
new(body, content_type)
click to toggle source
# File lib/api_hammer/body.rb, line 7 def initialize(body, content_type) @body = body @content_type = content_type end
Public Instance Methods
content_type_attrs()
click to toggle source
# File lib/api_hammer/body.rb, line 39 def content_type_attrs @content_type_attrs ||= ContentTypeAttrs.new(content_type) end
filtered(options)
click to toggle source
# File lib/api_hammer/body.rb, line 23 def filtered(options) @filtered ||= Body.new(begin if media_type == 'application/json' begin ApiHammer::Filtration::Json.new(body, options).filter rescue JSON::ParserError body end elsif media_type == 'application/x-www-form-urlencoded' ApiHammer::Filtration::FormEncoded.new(body, options).filter else body end end, content_type) end
jsonifiable()
click to toggle source
deal with the vagaries of getting the response body in a form which JSON gem will not cry about generating
# 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 # 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()
click to toggle source
# File lib/api_hammer/body.rb, line 43 def media_type content_type_attrs.media_type end
object()
click to toggle source
parses the body to an object
# 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