Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unify Message{Encryptor,Verifier} serializer config
In #42843 and #42846, several config settings were added to control the default serializer for `MessageEncryptor` and `MessageVerifier`, and to provide a migration path from a default `Marshal` serializer to a default `JSON` serializer: * `config.active_support.default_message_encryptor_serializer` * Supports `:marshal`, `:hybrid`, or `:json`. * `config.active_support.default_message_verifier_serializer` * Supports `:marshal`, `:hybrid`, or `:json`. * `config.active_support.fallback_to_marshal_deserialization` * Affects `:hybrid` for both `MessageEncryptor` and `MessageVerifier`. * `config.active_support.use_marshal_serialization` * Affects `:hybrid` for both `MessageEncryptor` and `MessageVerifier`. This commit unifies those config settings into a single setting, `config.active_support.message_serializer`, which supports `:marshal`, `:json_allow_marshal`, and `:json` values. So, for example, ```ruby config.active_support.default_message_encryptor_serializer = :hybrid config.active_support.default_message_verifier_serializer = :hybrid config.active_support.fallback_to_marshal_deserialization = true config.active_support.use_marshal_serialization = false ``` becomes ```ruby config.active_support.message_serializer = :json_allow_marshal ``` and ```ruby config.active_support.default_message_encryptor_serializer = :hybrid config.active_support.default_message_verifier_serializer = :hybrid config.active_support.fallback_to_marshal_deserialization = false config.active_support.use_marshal_serialization = false ``` becomes ```ruby config.active_support.message_serializer = :json ``` This commit also replaces `ActiveSupport::JsonWithMarshalFallback` with `ActiveSupport::Messages::SerializerWithFallback`, which implements a generic mechanism for serializer fallback. The `:marshal` serializer uses this mechanism too, so ```ruby config.active_support.default_message_encryptor_serializer = :hybrid config.active_support.default_message_verifier_serializer = :hybrid config.active_support.fallback_to_marshal_deserialization = false config.active_support.use_marshal_serialization = true ``` becomes ```ruby config.active_support.message_serializer = :marshal ``` Additionally, the logging behavior of `JsonWithMarshalFallback` has been replaced with notifications which include the names of the intended and actual serializers, as well as the serialized and deserialized message data. This provides a more targeted means of tracking serializer fallback events. It also allows the user to "silence" such events, if desired, without an additional config setting. All of these changes make it easier to add migration paths for new serializers such as `ActiveSupport::MessagePack`.
- Loading branch information
1 parent
016b796
commit 9fbfd81
Showing
22 changed files
with
411 additions
and
675 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 0 additions & 42 deletions
42
activesupport/lib/active_support/json_with_marshal_fallback.rb
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
activesupport/lib/active_support/messages/serializer_with_fallback.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# frozen_string_literal: true | ||
|
||
require "active_support/notifications" | ||
|
||
module ActiveSupport | ||
module Messages # :nodoc: | ||
module SerializerWithFallback # :nodoc: | ||
def self.[](format) | ||
SERIALIZERS.fetch(format) | ||
end | ||
|
||
def load(dumped) | ||
format = detect_format(dumped) | ||
|
||
if format == self.format | ||
_load(dumped) | ||
elsif format && fallback?(format) | ||
payload = { serializer: SERIALIZERS.key(self), fallback: format, serialized: dumped } | ||
ActiveSupport::Notifications.instrument("message_serializer_fallback.active_support", payload) do | ||
payload[:deserialized] = SERIALIZERS[format]._load(dumped) | ||
end | ||
else | ||
raise "Unsupported serialization format" | ||
end | ||
end | ||
|
||
private | ||
def detect_format(dumped) | ||
case | ||
when MarshalWithFallback.dumped?(dumped) | ||
:marshal | ||
when JsonWithFallback.dumped?(dumped) | ||
:json | ||
end | ||
end | ||
|
||
def fallback?(format) | ||
format != :marshal | ||
end | ||
|
||
module AllowMarshal | ||
private | ||
def fallback?(format) | ||
super || format == :marshal | ||
end | ||
end | ||
|
||
module MarshalWithFallback | ||
include SerializerWithFallback | ||
extend self | ||
|
||
def format | ||
:marshal | ||
end | ||
|
||
def dump(object) | ||
Marshal.dump(object) | ||
end | ||
|
||
def _load(dumped) | ||
Marshal.load(dumped) | ||
end | ||
|
||
MARSHAL_SIGNATURE = "\x04\x08" | ||
|
||
def dumped?(dumped) | ||
dumped.start_with?(MARSHAL_SIGNATURE) | ||
end | ||
end | ||
|
||
module JsonWithFallback | ||
include SerializerWithFallback | ||
extend self | ||
|
||
def format | ||
:json | ||
end | ||
|
||
def dump(object) | ||
ActiveSupport::JSON.encode(object) | ||
end | ||
|
||
def _load(dumped) | ||
ActiveSupport::JSON.decode(dumped) | ||
end | ||
|
||
JSON_START_WITH = /\A(?:[{\["]|-?\d|true|false|null)/ | ||
|
||
def dumped?(dumped) | ||
JSON_START_WITH.match?(dumped) | ||
end | ||
|
||
private | ||
def detect_format(dumped) | ||
# Assume JSON format if format could not be determined. | ||
super || :json | ||
end | ||
end | ||
|
||
module JsonWithFallbackAllowMarshal | ||
include JsonWithFallback | ||
include AllowMarshal | ||
extend self | ||
end | ||
|
||
SERIALIZERS = { | ||
marshal: MarshalWithFallback, | ||
json: JsonWithFallback, | ||
json_allow_marshal: JsonWithFallbackAllowMarshal, | ||
} | ||
end | ||
end | ||
end |
Oops, something went wrong.