Class: ApiHammer::Faraday::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/api_hammer/faraday/request_logger.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request_env, response_env) ⇒ Request

Returns a new instance of Request.



9
10
11
12
# File 'lib/api_hammer/faraday/request_logger.rb', line 9

def initialize(request_env, response_env)
  @request_env = request_env
  @response_env = response_env
end

Instance Attribute Details

#request_envObject (readonly)

Returns the value of attribute request_env.



14
15
16
# File 'lib/api_hammer/faraday/request_logger.rb', line 14

def request_env
  @request_env
end

#response_envObject (readonly)

Returns the value of attribute response_env.



15
16
17
# File 'lib/api_hammer/faraday/request_logger.rb', line 15

def response_env
  @response_env
end

Instance Method Details

#response_bodyObject

deal with the vagaries of getting the response body in a form which JSON gem will not cry about generating



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/api_hammer/faraday/request_logger.rb', line 19

def response_body
  instance_variable_defined?(:@response_body) ? @response_body : @response_body = catch(:response_body) do
    unless response_env.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([response_env.body])
        throw :response_body, response_env.body
      rescue
        # otherwise return nil - don't know what to do with whatever this object is 
        throw :response_body, nil
      end
    end

    # first try to change the string's encoding per the Content-Type header 
    content_type = response_env.response_headers['Content-Type']
    response_body = response_env.body.dup
    unless response_body.valid_encoding?
      # I think this always comes in as ASCII-8BIT anyway so may never get here. hopefully.
      response_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 response_body.dup.force_encoding(charset).valid_encoding?
          response_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([response_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?)
      if try_utf8 && response_body.dup.force_encoding('UTF-8').valid_encoding?
        response_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. 
        response_body = response_body.codepoints.to_a
      end
    end
    response_body
  end
end