Module: VCR::Normalizers::Body::ClassMethods

Defined in:
lib/vcr/structs.rb

Instance Method Summary collapse

Instance Method Details

#body_from(hash_or_string) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/vcr/structs.rb', line 15

def body_from(hash_or_string)
  return hash_or_string unless hash_or_string.is_a?(Hash)
  hash = hash_or_string

  if hash.has_key?('base64_string')
    base64_decoded = hash['base64_string'].unpack1('m')
    force_encode_string(base64_decoded, hash['encoding'])
  else
    try_encode_string(hash['string'], hash['encoding'])
  end
end

#force_encode_string(string, encoding) ⇒ Object



27
28
29
30
# File 'lib/vcr/structs.rb', line 27

def force_encode_string(string, encoding)
  return string unless encoding
  string.force_encoding(encoding)
end

#try_encode_string(string, encoding_name) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/vcr/structs.rb', line 32

def try_encode_string(string, encoding_name)
  return string if encoding_name.nil? || string.nil?

  encoding = Encoding.find(encoding_name)
  return string if string.encoding == encoding

  # ASCII-8BIT just means binary, so encoding to it is nonsensical
  # and yet "\u00f6".encode("ASCII-8BIT") raises an error.
  # Instead, we'll force encode it (essentially just tagging it as binary)
  return string.force_encoding(encoding) if encoding == Encoding::BINARY

  string.encode(encoding)
rescue EncodingError => e
  struct_type = name.split('::').last.downcase
  warn "VCR: got `#{e.class.name}: #{e.message}` while trying to encode the #{string.encoding.name} " +
        "#{struct_type} body to the original body encoding (#{encoding}). Consider using the " +
        "`:preserve_exact_body_bytes` option to work around this."
  return string
end