diff --git a/lib/rollbar/encoding.rb b/lib/rollbar/encoding.rb index fd81513f..07c54030 100644 --- a/lib/rollbar/encoding.rb +++ b/lib/rollbar/encoding.rb @@ -1,21 +1,27 @@ module Rollbar module Encoding - def self.encode(object) - can_be_encoded = object.is_a?(Symbol) || object.is_a?(String) - - return object unless can_be_encoded - - encoding_class.new(object).encode + class << self + attr_accessor :encoding_class end - def self.encoding_class + def self.setup if String.instance_methods.include?(:encode) require 'rollbar/encoding/encoder' - Encoder + self.encoding_class = Rollbar::Encoding::Encoder else require 'rollbar/encoding/legacy_encoder' - LegacyEncoder + self.encoding_class = Rollbar::Encoding::LegacyEncoder end end + + def self.encode(object) + can_be_encoded = object.is_a?(String) || object.is_a?(Symbol) + + return object unless can_be_encoded + + encoding_class.new(object).encode + end end end + +Rollbar::Encoding.setup diff --git a/lib/rollbar/encoding/encoder.rb b/lib/rollbar/encoding/encoder.rb index e1fe7551..dc761c3c 100644 --- a/lib/rollbar/encoding/encoder.rb +++ b/lib/rollbar/encoding/encoder.rb @@ -4,6 +4,8 @@ class Encoder ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII] ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1] ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' } + UTF8 = 'UTF-8'.freeze + BINARY = 'binary'.freeze attr_accessor :object @@ -13,8 +15,14 @@ def initialize(object) def encode value = object.to_s + encoding = value.encoding - encoded_value = force_encoding(value).encode(*encoding_args(value)) + # This will be most of cases so avoid force anything for them + if encoding == ::Encoding::UTF_8 && value.valid_encoding? + encoded_value = value + else + encoded_value = force_encoding(value).encode(*encoding_args(value)) + end object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value end @@ -34,6 +42,7 @@ def detect_encoding(v) ALL_ENCODINGS.detect do |encoding| begin + # Seems #codepoints is faster than #valid_encoding? value.force_encoding(encoding).encode(::Encoding::UTF_8).codepoints true rescue @@ -43,8 +52,8 @@ def detect_encoding(v) end def encoding_args(value) - args = ['UTF-8'] - args << 'binary' if ASCII_ENCODINGS.include?(value.encoding) + args = [UTF8] + args << BINARY if ASCII_ENCODINGS.include?(value.encoding) args << ENCODING_OPTIONS args diff --git a/lib/rollbar/encoding/legacy_encoder.rb b/lib/rollbar/encoding/legacy_encoder.rb index c86dee7a..f6192147 100644 --- a/lib/rollbar/encoding/legacy_encoder.rb +++ b/lib/rollbar/encoding/legacy_encoder.rb @@ -1,18 +1,20 @@ require 'iconv' module Rollbar - class LegacyEncoder - attr_accessor :object + module Encoding + class LegacyEncoder + attr_accessor :object - def initialize(object) - @object = object - end + def initialize(object) + @object = object + end - def encode - value = object.to_s - encoded_value = ::Iconv.conv('UTF-8//IGNORE', 'UTF-8', value) + def encode + value = object.to_s + encoded_value = ::Iconv.conv('UTF-8//IGNORE', 'UTF-8', value) - object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value + object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value + end end end end