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

Defined in:
lib/vcr/structs.rb

Instance Method Summary collapse

Instance Method Details

#body_from(hash_or_string) ⇒ Object


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

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')
    string = Base64.decode64(hash['base64_string'])
    force_encode_string(string, hash['encoding'])
  else
    try_encode_string(hash['string'], hash['encoding'])
  end
end

#force_encode_string(string, encoding) ⇒ Object


29
30
31
32
# File 'lib/vcr/structs.rb', line 29

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

#try_encode_string(string, encoding) ⇒ Object


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

def try_encode_string(string, encoding)
  return string if encoding.nil? || string.encoding.name == 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 == "ASCII-8BIT"

  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